As a newcomer to Ionic 3 & Angular, I encountered a challenge with the *ngFor and .subscribe() method. Please bear with me if this question seems simple. I attempted to understand the behavior of the http.get(..).map(..).subscribe() function when combined with *ngFor to manage an array of objects and display the records to the user using *ngFor in the .html template file, but I am struggling to comprehend *ngFor's peculiar behavior.
In my Ionic 3 App, I fetch data from an API and store it in a component variable named "users," which is defined as follows in the component .ts file -
users: Array<any>;;
I have the following component function that populates the users array with data -
addUser(count: number) {
this.http.get('https://randomuser.me/api/?results=' + count)
.map(data => data.json().results)
.subscribe(result => {
for (let val of result) {
this.users.push(val);
}
})
}
Initially, I retrieve data for 10 users from the API using the above component function by simply calling it within my ngAfterViewInit() function like -
this.addUser(10);
This provides me with 10 user record objects in my "users" array, which I display to the user in the .html file as follows -
<ion-card *ngFor="let user of users">
{{user.email}}
</ion-card>
At this point, *ngFor places the last array element first in the view and renders the records in descending order, starting from index 9 to 0 (LIFO order).
Subsequently, I remove the last element from the users array using users.pop(); and add another element at the beginning at index 0 by shifting the current elements using users.unshift(..) in the following function called addNewUser(1); -
addNewUser(count: number) {
this.http.get('https://randomuser.me/api/?results=' + count)
.map(data => data.json().results)
.subscribe(result => {
for (let val of result) {
this.users.unshift(val);
}
})
}
At this moment, considering the initial array with 10 elements, the last object at index 9 has been removed and another element at index 0 has been added, causing the previous elements at indexes 0-8 to shift to indexes 1-9.
Upon doing this, my view updates due to *ngFor, and surprisingly this time it shows the recently inserted element first from the array of objects, which contradicts the previous order followed by *ngFor in rendering elements on the screen.
Why does *ngFor in Ionic 3 display the recently added object element first from the array of objects, which is dependent on the .subscribe() method. I am genuinely puzzled by this.
I truly need clarification on *ngFor and subscribe(). Kindly assist me.
Note: The API mentioned above is publicly accessible for testing, and you may call it to check the response structure. A sample API response is provided below on calling https://randomuser.me/api/?results=1 -
{
"results": [
{
"gender": "male",
"name": {
"title": "mr",
"first": "daniel",
"last": "stoll"
},
"location": {
"street": "9719 tannenweg",
"city": "cottbus/chosebuz",
"state": "bremen",
"postcode": 81443
},
"email": "example@email.com",
"login": {
"username": "greenleopard994",
"password": "chat",
"salt": "OUjisBdQ",
"md5": "8148d51998f3fef835a5f3979218c181",
"sha1": "131ae09d045b345efe36a330bf17a450b76f7de3",
"sha256": "94c3a362b5f516d0fb1d4e9dbb632d32d57b8886d5cc7bf0d5cedc99e7d55219"
},
"dob": "1957-04-26 22:07:14",
"registered": "2002-04-29 10:57:34",
"phone": "0556-4348870",
"cell": "0172-5116200",
"id": {
"name": "",
"value": null
},
"picture": {
"large": "https://randomuser.me/api/portraits/men/14.jpg",
"medium": "https://randomuser.me/api/portraits/med/men/14.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/men/14.jpg"
},
"nat": "DE"
}
],
"info": {
"seed": "8fd4afe85884c767",
"results": 1,
"page": 1,
"version": "1.1"
}
}
Refer to this example showing my issue: Example Link