简体   繁体   中英

ngFor over object populated from promise in Angular 2

I'm parsing a zip file with images that I want to reference with a blobURL in a filesFromZip object, and iterate over it with ngFor to show the images on the page.

It looks like this

filesFromZip = {};
let zip = new JSZip();

zip.loadAsync(zipfileFromInput)
  .then(function (zip) {
    for (let file in zip.files) {

    let fileInZip = zip.files[file];

    zip.file(fileInZip.name)
      .async("arraybuffer")
      .then(function (content) {
        let buffer = new Uint8Array(content);
        let blob = new Blob([buffer.buffer]);

        // here is where I want to push this object into the filesFromZip object somehow....
        return {
          fileName: fileInZip.name,
          blobURL: URL.createObjectURL(blob)
        };
    });
   }
  });

in the template:

<md-card *ngFor="let file of filesFromZip">
  <h3 md-line>{{file.fileName}}</h3>
  <img src="{{file.blobURL}}">
</md-card>

How can I get the data from the promise to filesFromZip ?

I've tried to just push it into filesFromZip but that gives me this error:

error_handler.js:47 EXCEPTION: Uncaught (in promise): TypeError: Cannot read property 'async' of null

I'm really struggling with asynchronicity and Angular 2. Somebody who can send me in the right direction?

First, you cannot iterate over a plain object with the *ngFor directive, so filesFromZip should be an array.

this.filesFromZip = [];
zip.loadAsync(zipfileFromInput)
  .then((zip)=> {
    for (let file in zip.files) {
      let fileInZip = zip.files[file];
      zip.file(fileInZip.name)
        .async("arraybuffer")
        .then((content)=> {
          let buffer = new Uint8Array(content);
          let blob = new Blob([buffer.buffer]);
          // here is where I want to push this object into the filesFromZip object somehow....
          this.filesFromZip.push({
            fileName: fileInZip.name,
            blobURL: URL.createObjectURL(blob)
          });
      });
   }
  });

or you can use Promise.all() that will create a promise from an iterable of Promise and then use the async pipe :

javascript :

this.filesFromZip = Promise.all(
  zip.loadAsync(zipfileFromInput)
    .then((zip)=> {
      let out=[];
      for (let file in zip.files) {
        let fileInZip = zip.files[file];
        out.push(zip.file(fileInZip.name)
          .async("arraybuffer")
          .then((content)=> {
            let buffer = new Uint8Array(content);
            let blob = new Blob([buffer.buffer]);
            // here is where I want to push this object into the filesFromZip object somehow....
            this.filesFromZip.push({
              fileName: fileInZip.name,
              blobURL: URL.createObjectURL(blob)
            });
        }));
    }
    return out;
    });
)

template :

<md-card *ngFor="let file of filesFromZip|async">
  <h3 md-line>{{file.fileName}}</h3>
  <img src="{{file.blobURL}}">
</md-card>

However, your main problem here seems to be that zip.file(fileInZip.name) is returning null

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM