2

I can print the array in console but I can't get the length and I can't access first element

I am working on a project, I come across with this issue, where I can print the array in console but I can't get the length and I can't access first element also.

code:

checkout.component.ts:

ngOnInit() {
    this.booksInCheckout = this.checkoutService.getCheckoutBooks();
    console.log(this.booksInCheckout); // for array
    console.log(this.booksInCheckout.length); // for length of array
    console.log(this.booksInCheckout[0]); // for first element
}

checkout.service.ts:

getCheckoutBooks(): Checkout2[] {
    console.log('hey hello');
    this.booksInCheckout1 = [];
    this.booksInCheckout2 = [];
    this.userID = +localStorage.getItem('id');
    this.userService.getUserById(this.userID).subscribe(user => {
        this.booksInCheckout1 = user.checkout;
        for (let i = 0; i < this.booksInCheckout1.length; i++) {
            this.bookService
                .getBook(this.booksInCheckout1[i].bookId)
                .subscribe(book => {
                    this.daysRemaining = Math.ceil(
                        Math.abs(
                            new Date(
                                this.booksInCheckout1[i].endDate
                            ).getTime() - this.today.getTime()
                        ) / this.ONEDAY
                    );
                    this.booksInCheckout2.push(
                        new Checkout2(
                            book,
                            new Date(
                                this.booksInCheckout1[i].startDate
                            ).getMonth() +
                                1 +
                                '/' +
                                new Date(
                                    this.booksInCheckout1[i].startDate
                                ).getDate() +
                                '/' +
                                new Date(
                                    this.booksInCheckout1[i].startDate
                                ).getFullYear(),
                            new Date(
                                this.booksInCheckout1[i].endDate
                            ).getMonth() +
                                1 +
                                '/' +
                                new Date(
                                    this.booksInCheckout1[i].endDate
                                ).getDate() +
                                '/' +
                                new Date(
                                    this.booksInCheckout1[i].endDate
                                ).getFullYear(),
                            this.booksInCheckout1[i].status,
                            this.daysRemaining
                        )
                    );
                });
        }
        console.log(this.booksInCheckout2.length);
    });

    return this.booksInCheckout2;
}

enter image description here

3
  • In the screenshot, console shows length as 12. What's the issue? Commented Feb 18, 2019 at 6:58
  • In the next line, the length is 0. Commented Feb 18, 2019 at 9:29
  • I was new to asynchronous behavior, In my service, I should return the array inside subscribe. All the below mentioned answers are valid. Thanks, everyone. Commented Apr 26, 2020 at 8:35

3 Answers 3

5

This is happening because you are not awaiting the service. What happens is that the data has not come from the server and u are console logging its value.

let fetchData=async (params:any)=>{
    this.booksInCheckout = await this.checkoutService.getCheckoutBooks();// getting array value service
    //other code here
}

async function fetchData( params:any)=>{
    this.booksInCheckout = await this.checkoutService.getCheckoutBooks();// getting array value service
    //other code here
}

use one of the below mentioned function implementation for your service.

//code for service 
 function getCheckoutBooks(){
return http.get();
}


 
async function getCheckoutBooks(){
const booksData : any = await http.get();

return booksData;
}

The following code should work.

ngOnInit() {
   this.checkoutService.getCheckoutBooks().subscribe((booksInCheckout)=>{
    console.log(booksInCheckout); // for array
    console.log(booksInCheckout.length); // for length of array
    console.log(booksInCheckout[0]); // for first element
  
  });

}

You are facing this problem beacuse you are calling an asynchronous function but due to the asynchronous nature of javascript, the code below the function gets executed before the asynchronous task completes.

So here i have added a callback for the asynchronous task. Hope it helps :)

Sign up to request clarification or add additional context in comments.

4 Comments

Hi Sagar, Thanks for your reply. But, when I try this. I get error 'await expression is allowed only within an async function.' If I make the function async then also the problem persist.
You also need to assign your services as async await
change your service as per one of the above implementation. As you have not posted the code of your service i posted based on my assumptions. If the above code does not help. please post the code of your CheckoutService.
Thank you sagar for your response, I have updated my code and I couldn't figure out what went wrong, please have a look.
1

The reason is - Because your method this.checkoutService.getCheckoutBooks() is asynchronous in nature and you are trying to console before the data is fetched actually.

this.booksInCheckout = this.checkoutService.getCheckoutBooks();// Async Call

To sort out this problem either use subscribe to deal with async call or you can use console within the getCheckoutBooks method or maybe async in template side too.

Comments

0

Your are calling async services which doesn't not wait for your response. so, your next statement is getting executed first.

so if your are using ToPromise use can use .then:

this.checkoutService.getCheckoutBooks().then(res=> { this.booksInCheckout = res; console.log(this.booksInCheckout)});

or you can use await to keep waiting for response: this.booksInCheckout = await this.checkoutService.getCheckoutBooks();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.