Unable to retrieve the size of the dynamically generated array within the ngOnInit() lifecycle hook in Angular

Recently, I encountered an issue where I couldn't retrieve the length of a dynamically generated array in my Angular application's ngOnInit() method.

@Component({
  selector: 'rise-our-champions',
  templateUrl: './our-champions.component.html',
  styleUrls: ['./our-champions.component.css']
})
export class OurChampionsComponent implements OnInit {

champs: any = [];

ngOnInit() {
    this.getChampions(0, 12, 'created_at', 'desc', this.campaignId); 
    console.log(this.champs);
    console.log(this.champs.length); //<================= This displays 0 where as my array populates with 4 values.
  }

  getChampions(offset: any, size: any, sort: any, order: any, id: any) {

    this._restApiService.getCampaignChampion(offset, size, sort, order, id).subscribe(
  data => {
    // this.champions = data['champions']
    data['champions'].forEach((champion: any) => {
      this.champs.push(champion);
    });

    if (data['champions'].length < 12) {
      this.showMore = false;
    } else {
      this.showMore = true;
    }
  },
  error => {
    if (error.status == 400) {
      this.router.navigate(['/error']);
    } else {
      this.errorMessage = <any>error,
        this.missionService.announceMissionToShowCustomAlert({
          requestType: FeatureType.showCustomAlert,
          title: 'Error',
          message: '<p>' + this.errorMessage + '</p>',
          redirectType: FeatureType.isError
        })
    }
  },
  () => {

  }
);

}

Upon calling the function within the ngOnInit() lifecycle hook, the output displayed did not show the correct array length. Here is a snapshot for reference: https://i.sstatic.net/tXXOD.png

Answer №1

Due to the asynchronous nature of the call, your console.log() statement prints before the value is available. To ensure it displays the correct data, move the console.log() operation inside the subscribe function of your getChampions() method:

getChampions(offset: any, size: any, sort: any, order: any, id: any) {
  this._restApiService.getCampaignChampion(offset, size, sort, order, id).subscribe(
    data => {
      // this.champions = data['champions']
      data['champions'].forEach((champion: any) => {
      this.champs.push(champion);
    });

    if (data['champions'].length < 12) {
      this.showMore = false;
    } else {
      this.showMore = true;
    }
  },
  error => {
    if (error.status == 400) {
      this.router.navigate(['/error']);
    } else {
      this.errorMessage = <any>error,
        this.missionService.announceMissionToShowCustomAlert({
          requestType: FeatureType.showCustomAlert,
          title: 'Error',
          message: '<p>' + this.errorMessage + '</p>',
          redirectType: FeatureType.isError
        })
    }
  },
  () => {
     // THIS IS EXECUTED AFTER THE SUBSCRIBE COMPLETES
     console.log(this.champions);
  }
}

Answer №2

Your function getChampions initiates an asynchronous API call to the server, causing your console.log statements to run before champs is properly set.

To fix this issue, make sure to return the service call and subscribe to it in the ngOnInit method. Utilize the .map hook for data manipulation within this.getChampions like below:

    @Component({
      selector: 'rise-our-champions',
      templateUrl: './our-champions.component.html',
      styleUrls: ['./our-champions.component.css']
    })
    export class OurChampionsComponent implements OnInit {

      champs: any = [];

      ngOnInit() {
        this.getChampions(0, 12, 'created_at', 'desc', this.campaignId)
          .subscribe(() => {
            console.log(this.champs);
            console.log(this.champs.length);
          });
      }

      getChampions(offset: any, size: any, sort: any, order: any, id: any) {

    return this._restApiService.getCampaignChampion(offset, size, sort, order, id)
      .map(data => {
        // this.champions = data['champions']
        this.champs = data.champions;
        this.showMore = data.champions.length > 11;
      })
      .catch(error => {
        if (error.status == 400) {
          this.router.navigate(['/error']);
        } else {
          this.errorMessage = <any>error;
           this.missionService.announceMissionToShowCustomAlert({
              requestType: FeatureType.showCustomAlert,
              title: 'Error',
              message: '<p>' + this.errorMessage + '</p>',
              redirectType: FeatureType.isError
            })
        }
      });
}

    }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Obtaining data from a JSON response: A step-by-step

After receiving a JSON result, which contains only one array as shown below: { id: "5", client: "8", } id: 5 client: 8 I am trying to access it using the following function: getClient(url: string){ this.clientService.client(this.clientUrl).subsc ...

Inconsistency in @nuxtjs/i18n locales after refreshing the page

I am currently working on an application where I am implementing language management, but I have encountered a difficulty. I am using the latest version of @nuxtjs/i18n. Changing the language successfully updates the URL and labels, yet upon refreshing the ...

Ways to enable automatic user logoff upon closing the tab

Currently, I am developing a DotNetNuke website and facing an issue where I need to automatically logout the user when they close the browser or tab. Can someone guide me on how to detect the browser close event and trigger the user logout successfully? ...

Exploring External Functions in Angular Beyond the Library

Transitioning from standard JavaScript to Angular has been a bit challenging for me, especially when working with the Google Places library (or any other asynchronous callback). Here is the code snippet: var sparkApp = angular.module('sparkApp' ...

Don't forget about managing cookies in JavaScript!

Currently, I am developing a left sidebar menu that expands and collapses upon clicking a button. I need to find a way to save the state of the menu, whether it is expanded or collapsed, so that when the page is refreshed, the same class will still be app ...

Utilizing Angular JavaScript for detecting and setting up JDK installations

I am working on an application that requires the installation of Java JDK. Therefore, I need to develop a detection function for JDK in the system. If it is not found, I plan to install it using a setup provided by me and also set it in the system variabl ...

What is the best way to implement ES2023 functionalities in TypeScript?

I'm facing an issue while trying to utilize the ES2023 toReversed() method in TypeScript within my Next.js project. When building, I encounter the following error: Type error: Property 'toReversed' does not exist on type 'Job[]'. ...

What is the best way to verify the return value of a method when calling it from an

Can a method be called and return a value from an HTML template within double curly braces, like {{method-name}}? Answer: Yes. However, I am struggling to compare the return value. How can I do it? My scenario involves calling a method with arguments, p ...

Refreshing the child component based on the child's action and sending information to the parent in a React application

Within my Parent Component, I am utilizing an Ajax call to populate two children Components. C1 requires the data only once, while C2 has the ability to fetch additional data through subsequent Ajax calls and needs to render accordingly. I find it more co ...

Configuring ESLint and Prettier with the Airbnb style guide for TypeScript in a React Native (Expo) project

I have been struggling with setting up linting and formatting for my React Native project for a while now. Despite following various tutorials, I still encounter setup issues. My project consists of a Django backend and a React Native frontend. I began im ...

Shifting a collection of dictionaries using a fixed text value

My scenario involves three variables with the same type: const foo = { name: "foo", age: 12, color: "red" } as const; const bar = { name: "bar", age: 46, color: "blue" } as const; const baz = { name: "baz", ...

Troubleshooting: 404 error with jQuery Ajax POST method

Recently, I came across an AJAX script that caught my attention. Here is how it looks: jQuery.ajax({ url: 'http://localhost/?page_id=104256', type: 'POST', data: { name : &apo ...

Discovering the 3D coordinates of a point that is perpendicular to the midpoint of a line

(I am working with Javascript/Typescript and Three.js) Given two vectors, let's say {x:1, y:3, z:5} and {x:7, y:8, z:10}, I have a direct straight line connecting them. At the midpoint of this line, envision a disc with a radius of 1 that is perpend ...

Deactivate additional fields when choosing an option from the drop-down selection menu

When designing a form with a select dropdown that displays various options, I encountered an issue. I want to disable certain fields if a specific option is chosen from the dropdown. For instance, if "Within Company" is selected in the transaction type, I ...

Implementing Voting Functionality with Ajax Submission

Can anyone help me with getting ajax functionality to work properly for my Acts_As_Votable buttons? Here's the current code I have: post_controller.rb def favorite @post = Post.find(params[:id]) @post.upvote_from current_user respond_to do |f ...

What is the best way to connect a ref to a stateless component in React?

I need help creating a stateless component with an input element that can be validated by the parent component. In my code snippet below, I'm facing an issue where the input ref is not being assigned to the parent's private _emailAddress propert ...

Ensuring accurate properties are sent to popup notifications

As a newcomer to a React & ASP.NET project, I am facing a challenge in displaying upload status notifications. The task may seem simple, but I need help in figuring out how to create popup notifications that indicate which files have been successfully uplo ...

Sending JSON data from a JSP page to JavaScript

I am facing a challenge in returning a JSON Object/Array from JSP to JavaScript. I am uncertain about how to import a JSP file into JS. The JSON Array has been filled with values retrieved from the database. main.js: $(document).ready(function() { ...

Utilizing cookies to track the read status of articles - markers for reference

Currently, I am in the process of developing a website and am interested in implementing a feature that allows users to track which articles they have read. I am considering adding a small circle next to each article heading to signify whether it has been ...

Looking for a speedy solution with a [PHP function] that needs to be converted to a [JavaScript function

Looking for a quick favor - can anyone help me out with this: static function make_url_safe($z){ $z = strtolower($z); $z = preg_replace('/[^a-zA-Z0-9\s] /i', '', $z); $z = str_ireplace(' ', '-', $z) ...