Reputation: 377
I have a method which assigns an array returned from from a http request to another array. The issue is that it appears that after the method completes, the array with the new values becomes empty.
Method with http request.
loadBookingFullRowDataRequest(rowId: number) {
this.bookingFullRowData[rowId] = [];
this.bookingService.getAllBookingData().subscribe(res => {
this.bookingFullRowData = <Booking[]>res[rowId];
console.log('all booking data: ', this.bookingFullRowData, 'rowId: ', rowId);
for (const item of this.bookingFullRowData) {
const itemId = `${item['title']}-rowid-${item['rowid']}-proj-${item['proj']}`;
this.bookingsForm.addControl(itemId, new FormControl(
`${item['content']}`
));
}
});
}
Method which attempts to use the data from the updated array.
launchModal(element) {
const elementId = (event.target as Element).id;
const elementIdArray = String(elementId).split('-');
this.currentRow = parseInt(elementIdArray[2], 10);
this.loadBookingFullRowDataRequest(this.currentRow);
console.log('the whole loaded dta:', this.bookingFullRowData, 'row: ', this.currentRow);
this.modalService.createModal('#bookings-form', null, this.dialogOptions);
}
The console.log just outputs an empty array.
Upvotes: 1
Views: 449
Reputation: 4175
As subscribe funciton is making an asynchronous call, you need to make sure you are using data after call is completed.
Subscribe has 3 parameters/sections.
Call is completed section
loadBookingFullRowDataRequest(rowId: number) {
this.bookingFullRowData[rowId] = [];
this.bookingService.getAllBookingData().subscribe(res => {
this.bookingFullRowData = <Booking[]>res[rowId];
console.log('all booking data: ', this.bookingFullRowData, 'rowId: ', rowId);
for (const item of this.bookingFullRowData) {
const itemId = `${item['title']}-rowid-${item['rowid']}-proj-${item['proj']}`;
this.bookingsForm.addControl(itemId, new FormControl(
`${item['content']}`
));
}
}, ()=> {console.log(error)}, // error
()=> // call is completed here you can do aftercall tasks { console.log('the whole loaded dta:', this.bookingFullRowData, 'row: ', this.currentRow); this.modalService.createModal('#bookings-form', null, this.dialogOptions)} ); }
Upvotes: 0
Reputation: 60558
The issue is that the getAllBookingData
method is asynchronous. That means that it issues a request but does not immediately get a response.
The function we pass into the subscribe method is basically a callback function that is executed when the response is returned.
That means that the code within
this.bookingService.getAllBookingData().subscribe()
// <-- HERE
Is executed at some later point in time.
So all of the code after this line:
this.loadBookingFullRowDataRequest(this.currentRow);
// Any code below here!!
console.log('the whole loaded dta:', this.bookingFullRowData, 'row: ', this.currentRow);
this.modalService.createModal('#bookings-form', null, this.dialogOptions);
is executed BEFORE the function passed into the subscribe method.
So to solve your issue, you need to move all code that needs to execute after the data is retrieved within the callback function:
loadBookingFullRowDataRequest(rowId: number) {
this.bookingFullRowData[rowId] = [];
this.bookingService.getAllBookingData().subscribe(res => {
this.bookingFullRowData = <Booking[]>res[rowId];
console.log('all booking data: ', this.bookingFullRowData, 'rowId: ', rowId);
for (const item of this.bookingFullRowData) {
const itemId = `${item['title']}-rowid-${item['rowid']}-proj-${item['proj']}`;
this.bookingsForm.addControl(itemId, new FormControl(
`${item['content']}`
));
}
console.log('the whole loaded dta:', this.bookingFullRowData, 'row: ', this.currentRow);
this.modalService.createModal('#bookings-form', null, this.dialogOptions);
});
}
As a side note, don't use .toPromise
Stick with Observables.
Upvotes: 2
Reputation: 276105
Your code is not waiting. Notice the comments below:
// Launch async task in terms of subscribe
this.loadBookingFullRowDataRequest(this.currentRow);
// use loaded data *without waiting*
console.log('the whole loaded dta:', this.bookingFullRowData, 'row: ', this.currentRow);
You need to use the data after subscribe is called.
Use toPromise
and then chain with then
. Docs : https://www.learnrxjs.io/operators/utility/topromise.html
Upvotes: 0