Issue
I am having a problem with subscribe running before it gets it's data. I have 3 components that need to have 3 pieces of data to load. So rather than call the backend 3 times, I put them all into one array loaded from the backend, and then divide between the 3 components on load. Some of the components need the same data.
So I have a service which gets the code from the backend. When my function gets the data back I load a setter function with the data called setFolderStore, and I have a getFolderStore function call. The problem is that my component seems to be running the getFolderStore, before I have set the data. I do this so that my other components can get the data, without having to re-run the call to the backend.
//Service
private folderStore = new BehaviorSubject<adminInterfaces.IfolderList[]>([]);
buildGallery(postData: any): Observable<any> {
return this.httpClient.post(this.apiUrl +'commander/readImagesFolders', postData).pipe(
map((postData:any)=>{
this.setFolderStore(postData.folderList);// this sets one part of my data.
return postData;
})
);
}
public setFolderStore(store:any) {
this.folderStore.next(store);
}
public getFolderStore(): Observable<Array<adminInterfaces.IfolderList>>{
return this.folderStore.asObservable();
}
In my first component I run buildGallery.
// First component
this.adminService.buildGallery(this.postData).subscribe(res => {
this.image = <gallery.IgalleryData>res.organise;
error => {
});
}
In my second component I have a console log. It runs once empty, and then runs again with the full data, but by that time I have already got an error, because I am setting an index from the data, which obviously fails. Surely it should wait for this.folderStore.next(store) to be run?
ngOnInit(): void {
this.getFolderStoreSubscribe = this.adminService.getFolderStore().subscribe((data) => {
let index = 0;
if(typeof data !== null){
console.log(data);
if (this._route.snapshot.queryParamMap.has('f')) {
this.currentFolderID = this._route.snapshot.queryParamMap.get('f');
index = data.findIndex(x => x.folder_id == this.currentFolderID);
this.folderName = data[index].name;// Here this is generating an error because the subscribe is running before I get the data.
}
}
});
}
So why is my subscribe running before it gets it's data, and is there a solution to the problem? Really the subscribe shouldn't run until after I have called setFolderStore.
Solution
BehaviourSubject (a type of subject) is used when you want set the initial value of the Subject and want to get one
previous value emitted by that subject in your subscribe block. So whenever you subscribe to it, it will emits current value which at the moment you have set to an empty state. I think there are two solutions:
First one (Recommended)
As you don't want the initial value, so should use Subject
instead of BehaviorSubject
. So your initialization would look like this:
//Service
private folderStore = new Subject<adminInterfaces.IfolderList[]>();
Second method (for some reason you want to use BehaviorSubject)
You could just check data[index]
for null before trying to access value, i.e.
if(data[index]) {
this.folderName = data[index].name;
}
But I'll recommend that you go with the first method.
Also a small comparison to help me choose which type of Subject
I want to create.
Answered By - HassanMoin
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.