I'm facing a classic http race issue, but I'm not familiar enough with Angular2 and Observable to resolve my case.
Here's a description of my bricks :
[ FormComponent ]
| |
1| |6
| |
[ MetadataService ] <----4 & 5----> [ TranslatorService ]
| |
2| |3
| |
[ Backend ]
The architecture seems simple but there's something wrong in the way I'm implementating this, as in the end in my view the metadata property is "undefined" and therefore *ngFor throws an error My first idea was to subscribe to the Observable in the component but I don't know how to deal with these Observables as I've got two services.
From my opinion the problem comes from the 4th step :
MetadataService
getFormMetaData(folderId: string, context: string){
let body = JSON.stringify({
folderId: folderId,
context: context
});
return this.http.post(this.uri, body, options)
.map( (res) => {
let body = res.json();
if (body.data){
return this.translatorService.getTranslatedElements(body.data);
}
}
);
}
It should return an Observable, but the map() method return the value of the TranslatorService, which is an array...
How should I do ?
edit : Here's is my FormComponent :
FormComponent
@Component({
template: `
<dynamic-form controls="formMetadata | async"></dynamic-form>
`,
providers: [MetadataService]
})
export class CustomerFormComponent {
formMetadata: any;
constructor(private metadataService: MetadataService) { }
ngOnInit() {
this.formMetadata = this.formMetadataService.getFormMetadata('FR75P00000012', 'UserInformation');
}
}
And my TranslatorService :
TranslatorService
getTranslatedElements(metadata: any) {
debugger; // It never breaks here
let elements = [];
metadata.forEach( (field) => {
...
elements.push(field);
} )
return elements;
}
Update :
Ok, I advanced a bit. It seems the problem comes from my async pipe, that I use in the FormComponent template to pass data to a child component.
Should this child component handle this kind of asyncronous data in a particular manner too ?
Solution How to waste hours to debug : forget to put your databinded properties inside brackets.
<dynamic-form controls="formMetadata"></dynamic-form>
should be
<dynamic-form [controls]="formMetadata"></dynamic-form>
That explains why DynamicFormComponent received a string as input...
Solution 2 Actually, I still had the problem of having the child component instanciated before even the subscribe function load datas. I've been able to resolve this by doing a <dynamic-form [controls]="formMetadata" *ngIf="formMetadata"></dynamic-form>
I couldn't use the async pipe, it didn't work. I don't know when the async trigger within the parent template, but it seems to be after the child component constructor() and noOnInit()
As described in http://reactivex.io/documentation/operators/map.html
The Map operator applies a function of your choosing to each item emitted by the source Observable, and returns an Observable that emits the results of these function applications.
So MetadataService should return an Observable of what returns this.translatorService.getTranslatedElements(body.data);
or an Observable of undefined in case of body.data is empty.
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.