2017-07-25 3 views
0

Ich verwende einen Dienst, um Bilder auf einen Server hochzuladen. Hier ist es:Angular 2 & Vanilla JS: Warten Sie, bis Bilder geladen werden, bevor Sie http-Anrufe tätigen.

addPictures(files: File[], folder: string): Observable<Parse.Object[]> { 
    let hasError = false; 
    for (let file of files) { 
    let [type, ext] = file.type.split('/'); 
    if (type.toLowerCase() !== 'image' || !environment.imgExts.includes(ext.toLowerCase())) { hasError = true; } 
    } 
    if (hasError) { return Observable.throw('Invalid extension detected'); } 

    let observables: Observable<Parse.Object>[] = []; 

    for (let file of files) { 
    // Get its size 
    let img = new Image(); 
    img.onload =() => { 
     // Create the Parse document 
     let parseImg = { url: '', type: file.type, width: img.width, height: img.height }; 
     // Upload it on Amazon and add it to DB 
     observables.push(this.addPicture(parseImg, file, folder)); 
     console.log('pushing to array'); 
    } 
    img.src = window.URL.createObjectURL(file); 
    } 
    console.log('forkjoin'); 
    return Observable.forkJoin(observables); 
} 

Alle Funktionen funktioniert gut. Das Problem, das ich gegenüberstelle, ist, dass, wenn ich img.onload benutze, der forkJoin nicht darauf wartet, bevor es feuert. Was ich möchte, ist warten Sie auf alle Bilder zu laden, dann Trig thribJoin, um sie alle senden.

Ich habe bereits versucht, mit einer Bedingung (wenn das letzte Element an Array geschoben wird, triggern Sie den ForkJoin), mit einem Betreff, aber das Problem ist, dass meine Komponente einen Fehler in den Zeilen Cannot read property 'subscribe' of undefined zurückgibt.

EDIT hier ist mein Code für thr fromEvent:

addPictures(files: File[], folder: string): Observable<Parse.Object[]> { 
    let hasError = false; 
    for (let file of files) { 
    let [type, ext] = file.type.split('/'); 
    if (type.toLowerCase() !== 'image' || !environment.imgExts.includes(ext.toLowerCase())) { hasError = true; } 
    } 
    if (hasError) { return Observable.throw('Invalid extension detected'); } 

    let observables: Observable<Parse.Object>[] = []; 

    for (let file of files) { 
    // Get its size 
    let img = this.fromImgEvent(file, window.URL.createObjectURL(file), folder); 
    observables.push(img); 
    } 
    console.log('forkjoin'); 
    return Observable.forkJoin(observables); 
} 

fromImgEvent(file: File, url: string, folder: string) { 
    return Observable.create(observer => { 
    let img = new Image(); 
    img.onload =() => { 
     // Create the Parse document 
     let parseImg = { url: '', type: file.type, width: img.width, height: img.height }; 
     // Upload it on Amazon and add it to DB 
     observer.next(this.addPicture(parseImg, file, folder)); 
     observer.complete(); 
    } 
    img.src = url; 
    }); 
} 
+0

Haben Sie den Operator "Observable.fromEvent" versucht, den onload ev zu hören als beobachtbar. – cyrix

+0

Nein, davon weiß ich nichts, könnten Sie ein kurzes Beispiel geben? – trichetriche

Antwort

0

Sie zum Beispiel verwenden könnte Observable.fromEvent oder ein beobachtbares selbst für eine Lade Bild erstellen wie folgt:

addPictures(files: File[], folder: string): Observable<Parse.Object[]> { 
 
    let hasError = false; 
 
    let data$ = files.map(file => { 
 
    let [type, ext] = file.type.split('/'); 
 
    if (type.toLowerCase() !== 'image' || !environment.imgExts.includes(ext.toLowerCase())) { 
 
     hasError = true; 
 
    } 
 
    return Observable.create(observer => { 
 
     let image = new Image(); 
 
     image.src = window.URL.createObjectURL(file); 
 
     image.onload = (e) => { 
 
      let parsedImage = { url: '', type: file.type, width: image.width, height: image.height }; 
 
      observer.next({ parsedImage, file }); 
 
      observer.complete(); 
 
     }; 
 
    }); 
 
    }; 
 
    if (hasError) { 
 
    return Observable.throw('Invalid extension detected'); 
 
    } 
 
    return Observable 
 
    .forkJoin(data$) 
 
    .toArray() 
 
    .switchMap(([parsedData]) => { 
 
     return Observable.forkJoin(
 
      parsedData.map(data => { 
 
       return this.addPicture(data.parsedImage, data.file, folder) 
 
      }) 
 
     ); 
 
    }); 
 
}

+0

Nur getestet, und das Gabelgelenk wird immer noch trigerred, bevor das Array der beobachtbaren Werte hat ... – trichetriche

+0

Kann man einen Plunkr mit einem Testfall hinzufügen? Oder fügen Sie Ihren Code mit dieser Erweiterung der Frage hinzu? – cyrix

+0

Warten Sie, ich habe vergessen, die HTTP-Aufrufe tatsächlich Ahah zu machen. Ich füge es hinzu und teste es, und ich lasse es Sie wissen! – trichetriche

Verwandte Themen