Filestack with Angular 2

你离开我真会死。 提交于 2020-01-23 12:53:22

问题


I'm trying to add an option to add an image in my Angular 2 App and wanted to use Filestack (formerly filepicker.io) to store the images. So I included these script tags in my index html file above </body>, as Filestack suggested (and put my API key in) and added the <input> field in my component html which displays the form to add a new recipe:

in index.html:

<script src="https://static.filestackapi.com/v3/filestack-0.5.0.js"></script>
<script>
    var url = '';
    var client = filestack.init('myApiKey');
    function showPicker() {
        client.pick({
            maxFiles: 1
        }).then(function(result) {
            url = JSON.stringify(result.filesUploaded[0].url)
        });
    }
</script>

in recipe-form.component.html:

<input type="button" value="Upload" onclick="showPicker()" />

Now that works perfectly fine, it uploads the image and if I add console.log(url) it also shows the url of the image. However, there seems to be no way to get that variable into the RecipeFormComponent where I want to add the url to the object I'm creating there. How could I do that?

I have found a lot of stuff about how to use Filestack with AngularJS, but not how to do this in Angular 2...

Is there anything you know of that could help me?


回答1:


Remove everything you have shown for index.html except for the script tag to load the API.

<script src="//static.filestackapi.com/v3/filestack-0.5.0.js"></script>

Then alter your component to incorporate the showPicker functionality

recipe-form.component.ts

declare const filestack: {
  init(apiKey: string): {
    pick({ maxFiles }: { maxFiles: number }):
      Promise<{ filesUploaded: { url: string }[] }> 
  }
};

@Component({
  // boilerplate and ceremony
})
export class RecipeFormComponent {
  uploadedFileUrls: string[] = [];

  async showPicker() {
    const client = filestack.init('myApiKey');
    const result = await client.pick({ maxFiles: 1 });
    const url = result.filesUploaded[0].url;
    this.uploadedFileUrls.push(url);
  }
}

To improve maintainability and testability, you should move all of the code with that accesses the filestack global into a dedicated service or services.

For example we could write a service like

// file-upload.service.ts
declare const filestack: {

  init(apiKey: string): {
    pick: (options: {maxFiles: number}) => Promise<{filesUploaded: {url: string}[]}>
  }
};

const client = filestack.init('myApiKey');

export default class {
  async uploadOne() {
    const result = await client.pick({ maxFiles: 1 });
    return {urls: result.filesUploaded.map(uploaded => uploaded.url)};
  }
}

we can consume it from components by using the service which wraps the API and provides the results that matter to our application

import FileUploadService from 'app/services/file-upload.service';

@Component({
  // boilerplate and ceremony
})
export class RecipeFormComponent {
  constructor(readonly fileUploadService: FileUploadService) {}

  uploadedFileUrls: string[] = [];

  async showPicker() {
    const {urls: [url]} = await this.fileUploadService.uploadOne();

    this.uploadedFileUrls.push(url);
  }
}

Additionally, if you're using a module loader like SystemJS, you would do well to remove the script tag itself, mapping and hiding its global nature via the loader.



来源:https://stackoverflow.com/questions/43459805/filestack-with-angular-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!