J'ai donc un sélecteur NGRX qui retourne un observable avec une gamme de contacts. Je souhaite mapper sur ce flux et pour chaque gamme de contacts, cartographier sur chaque contact individuel et faire une demande HTTP à Github pour récupérer leur image de profil et l'ajouter à l'objet de contact. Cependant, je ne sais pas comment faire cela sans vous retrouver avec un observable d'observable.
ci-dessous est ce que j'ai essayé, mais cela ne fonctionne pas. P>
Type 'Observable<Observable<Contact>[]>' is not assignable to type 'Observable<Contact[]>'. Type 'Observable<Contact>[]' is not assignable to type 'Contact[]'. Type 'Observable<Contact>' is missing the following properties from type 'Contact': first_name, last_name, job_title, location, company ts(2322)
3 Réponses :
Le problème ici est que vous exécutez un array.map code> qui renvoie une observable pour chaque
contact code>. Si vous souhaitez que l'observable renvoie le tableau rempli, vous voudrez quelque chose comme ceci:
this.contacts$: Observable<Contact[]> = this.store.select(getContacts).pipe(
// take the array and emit each value one by one
concatMap(contacts => from(contacts)),
// emit an array containing the contact and the corresponding githubInfo
concatMap(contact => forkJoin(of(contact), this.contactService.getGithub$(contact._id))),
// take the returned array and convert it to an Object
map(([contact, githubInfo]) => ({ ...contact, imageUrl: githubInfo.avatar_url})),
// concatenate everything into a final Array
toArray()
);
Merci, va! Ceci est assez proche, mais pour une raison quelconque, il n'engage aucune valeur. Si je supprimais le Toarray (), il émet des valeurs individuelles avec le bon imageURL attaché.
Je crois que le flux doit être complet pour Toarray () au travail
Votre sélecteur devrait terminer une fois qu'il a émis toutes ses valeurs, non?
Eh bien, il s'agit d'un sélecteur mémo-mémoire qui réaffirmera la matrice de contacts à tout moment la valeur de la valeur de NGRX Store change. Donc, il ne finit jamais vraiment. Je me trompe peut-être, mais je crois que c'est comme ça que ça marche.
Vous êtes complètement correct, désolé! Je ne pensais pas aux termes de NGRX! Vous avez quelques choix possibles si vous avez vraiment besoin d'un tableau. Vous pouvez utiliser Scan / Réduire des stratégies ou ajouter un Tuskuntil Code> Après avoir extrait la longueur de la matrice de contacts d'origine. Cela a-t-il du sens?
Ouais, je pensais que Scan () pourrait être nécessaire. Je vais jouer avec vos suggestions et voir si je peux obtenir une solution de travail. Merci!
Je suppose que tout dépend de la façon dont vous avez besoin de cet observable pour se comporter. Au lieu de fractionnement des choses avec le premier ConcaTMap code>, vous pouvez simplement utiliser un tableau
array.map code> pour l'observable pour émettre des tableaux complets à chaque fois. Si vous n'avez besoin que de cela pour émettre une fois (et ne pas être particulièrement réactif), vous pouvez ajouter un
prendre (1) code> au début du tuyau.
this.contacts$: Observable<Contact[]> = this.store.select(getContacts).pipe( map(contacts => { return contacts.map(contact => { return this.contactService.getGithub$(contact._id).pipe( map(githubInfo => { return { ...contact, imageUrl: githubInfo.avatar_url }; }) ); }); }), concatAll() ); Just add concatAll operator to pipe stream.
Les réponses sans formatage ni explication ne sont pas utiles.
Utiliser Switchmap CODE> Pour mapper votre
Contacts CODE> TRAY sur un observable qui exécute simultanément vos requêtes HTTP et les mapper sur un objet de contact étendu.
this.contacts$: Observable<Contact[]> = this.store.select(getContacts).pipe(
switchMap(contacts => forkJoin(
contacts.map(contact => this.contactService.getGithub$(contact._id).pipe(
map(gitHubInfo => ({ ...contact, imageUrl: githubInfo.avatar_url }))
))
))
);