nested loop error when displaying in html after retrieve from API
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I am new to ionic 3 and angular. Basically I wanted to create a list with header (data from MySQL database through PHP API). The header will display the category
while the items
will go to ion-item
section.
However when I try to call the 2nd ngFor
it throws me error as shown below in the picture. I notice a lot people use GET method while I am using POST method which are harder to find solution out there. Please enlighten, thanks in advance.
JSON
home.ts
this.storage.get('username').then((val) => {
let headers: any = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }),
options: any = { "username": val },
url: any = "path_to_my_api";
this.http.post(url, options, headers)
.subscribe((data: any) => {
this.prods = data.products;
},
(error: any) => {
console.log(error);
});
});
home.html
<ion-list *ngFor="let prod of prods | async">
<ion-list-header>
{{prod.category}}
</ion-list-header>
<ion-item *ngFor="let myitem of prod.item | async">
<ion-avatar item-start>
</ion-avatar>
<h2>haha{{myitem.code}}</h2>
</ion-item>
</ion-list>
angular ionic-framework ionic3
add a comment |
I am new to ionic 3 and angular. Basically I wanted to create a list with header (data from MySQL database through PHP API). The header will display the category
while the items
will go to ion-item
section.
However when I try to call the 2nd ngFor
it throws me error as shown below in the picture. I notice a lot people use GET method while I am using POST method which are harder to find solution out there. Please enlighten, thanks in advance.
JSON
home.ts
this.storage.get('username').then((val) => {
let headers: any = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }),
options: any = { "username": val },
url: any = "path_to_my_api";
this.http.post(url, options, headers)
.subscribe((data: any) => {
this.prods = data.products;
},
(error: any) => {
console.log(error);
});
});
home.html
<ion-list *ngFor="let prod of prods | async">
<ion-list-header>
{{prod.category}}
</ion-list-header>
<ion-item *ngFor="let myitem of prod.item | async">
<ion-avatar item-start>
</ion-avatar>
<h2>haha{{myitem.code}}</h2>
</ion-item>
</ion-list>
angular ionic-framework ionic3
According to the error message, item is an object, not an array.
– Ben Steward
Nov 24 '18 at 17:37
how to make it become an array? But in console it is array, am I right? So weird
– 4 Leave Cover
Nov 24 '18 at 17:39
No, your second ngfor is entirely unnecessary. You’ve already begun to iterate over the array.
– Ben Steward
Nov 24 '18 at 17:40
I want all the items to be grouped in the category, if I only use 1 ngfor, the category will display as duplicate for every single item.
– 4 Leave Cover
Nov 24 '18 at 17:42
Ok, I see. I will update my answer in a minute.
– Ben Steward
Nov 24 '18 at 17:45
add a comment |
I am new to ionic 3 and angular. Basically I wanted to create a list with header (data from MySQL database through PHP API). The header will display the category
while the items
will go to ion-item
section.
However when I try to call the 2nd ngFor
it throws me error as shown below in the picture. I notice a lot people use GET method while I am using POST method which are harder to find solution out there. Please enlighten, thanks in advance.
JSON
home.ts
this.storage.get('username').then((val) => {
let headers: any = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }),
options: any = { "username": val },
url: any = "path_to_my_api";
this.http.post(url, options, headers)
.subscribe((data: any) => {
this.prods = data.products;
},
(error: any) => {
console.log(error);
});
});
home.html
<ion-list *ngFor="let prod of prods | async">
<ion-list-header>
{{prod.category}}
</ion-list-header>
<ion-item *ngFor="let myitem of prod.item | async">
<ion-avatar item-start>
</ion-avatar>
<h2>haha{{myitem.code}}</h2>
</ion-item>
</ion-list>
angular ionic-framework ionic3
I am new to ionic 3 and angular. Basically I wanted to create a list with header (data from MySQL database through PHP API). The header will display the category
while the items
will go to ion-item
section.
However when I try to call the 2nd ngFor
it throws me error as shown below in the picture. I notice a lot people use GET method while I am using POST method which are harder to find solution out there. Please enlighten, thanks in advance.
JSON
home.ts
this.storage.get('username').then((val) => {
let headers: any = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }),
options: any = { "username": val },
url: any = "path_to_my_api";
this.http.post(url, options, headers)
.subscribe((data: any) => {
this.prods = data.products;
},
(error: any) => {
console.log(error);
});
});
home.html
<ion-list *ngFor="let prod of prods | async">
<ion-list-header>
{{prod.category}}
</ion-list-header>
<ion-item *ngFor="let myitem of prod.item | async">
<ion-avatar item-start>
</ion-avatar>
<h2>haha{{myitem.code}}</h2>
</ion-item>
</ion-list>
angular ionic-framework ionic3
angular ionic-framework ionic3
edited Nov 24 '18 at 18:51
georgeawg
35k115470
35k115470
asked Nov 24 '18 at 17:13
4 Leave Cover4 Leave Cover
89992751
89992751
According to the error message, item is an object, not an array.
– Ben Steward
Nov 24 '18 at 17:37
how to make it become an array? But in console it is array, am I right? So weird
– 4 Leave Cover
Nov 24 '18 at 17:39
No, your second ngfor is entirely unnecessary. You’ve already begun to iterate over the array.
– Ben Steward
Nov 24 '18 at 17:40
I want all the items to be grouped in the category, if I only use 1 ngfor, the category will display as duplicate for every single item.
– 4 Leave Cover
Nov 24 '18 at 17:42
Ok, I see. I will update my answer in a minute.
– Ben Steward
Nov 24 '18 at 17:45
add a comment |
According to the error message, item is an object, not an array.
– Ben Steward
Nov 24 '18 at 17:37
how to make it become an array? But in console it is array, am I right? So weird
– 4 Leave Cover
Nov 24 '18 at 17:39
No, your second ngfor is entirely unnecessary. You’ve already begun to iterate over the array.
– Ben Steward
Nov 24 '18 at 17:40
I want all the items to be grouped in the category, if I only use 1 ngfor, the category will display as duplicate for every single item.
– 4 Leave Cover
Nov 24 '18 at 17:42
Ok, I see. I will update my answer in a minute.
– Ben Steward
Nov 24 '18 at 17:45
According to the error message, item is an object, not an array.
– Ben Steward
Nov 24 '18 at 17:37
According to the error message, item is an object, not an array.
– Ben Steward
Nov 24 '18 at 17:37
how to make it become an array? But in console it is array, am I right? So weird
– 4 Leave Cover
Nov 24 '18 at 17:39
how to make it become an array? But in console it is array, am I right? So weird
– 4 Leave Cover
Nov 24 '18 at 17:39
No, your second ngfor is entirely unnecessary. You’ve already begun to iterate over the array.
– Ben Steward
Nov 24 '18 at 17:40
No, your second ngfor is entirely unnecessary. You’ve already begun to iterate over the array.
– Ben Steward
Nov 24 '18 at 17:40
I want all the items to be grouped in the category, if I only use 1 ngfor, the category will display as duplicate for every single item.
– 4 Leave Cover
Nov 24 '18 at 17:42
I want all the items to be grouped in the category, if I only use 1 ngfor, the category will display as duplicate for every single item.
– 4 Leave Cover
Nov 24 '18 at 17:42
Ok, I see. I will update my answer in a minute.
– Ben Steward
Nov 24 '18 at 17:45
Ok, I see. I will update my answer in a minute.
– Ben Steward
Nov 24 '18 at 17:45
add a comment |
1 Answer
1
active
oldest
votes
Try this
Logic:
this.http.post(url, options, headers)
.subscribe((data: any) => {
const categoryMap = data.products.reduce((categories, prod) => {
if (categories[prod.category]) {
categories[prod.category].push(prod);
} else {
categories[prod.category] = [prod];
}
return categories;
}, {});
this.categories = Object.keys(categoryMap).map(category => ({
category,
products: categoryMap[category]
});
}, (error: any) => {
console.log(error);
});
Template:
<ion-list *ngFor="let cat of categories | async">
<ion-list-header>
{{cat.category}}
</ion-list-header>
<ion-item *ngFor="let prod of cat.products | async"> <!-- not sure if async pipe is necessary here though -->
<ion-avatar item-start></ion-avatar>
<h2>haha{{prod.item.code}}</h2>
</ion-item>
</ion-list>
To clarify, the final structure of your data will look like this:
this.categories = [
{
category: "Beer Bottles",
products: [
{
item: {code: 'whatever'},
category: "Beer Bottles"
},
{
item: {code: 'something else'},
category: "Beer Bottles"
},
...etc.
]
},
{
category: "Beer Draught",
products: [ ...relevant products as above]
}
]
1
appreciated your effort. Let me have a look and get back soon.
– 4 Leave Cover
Nov 24 '18 at 19:44
Many thanks to you as it is working as expected now! Can I know why do we need have two category, one in outer and another one in products array? Btw I removed the async.
– 4 Leave Cover
Nov 25 '18 at 7:49
1
In this particular implementation, it would have been more trouble to try and remove the category from the individual products than it was worth for a Stack Overflow answer. You could certainly try to remove it, but it is probably not necessary.
– Ben Steward
Nov 25 '18 at 13:04
Indeed, I will probably do it in the future when I have more understanding on this part. Thanks a lot anyway :)
– 4 Leave Cover
Nov 25 '18 at 16:43
Hi Ben, for example I added a search bar. Can I implement the filter feature with this logic? The search bar can search for multiple fields e.g. code, desc, uom etc. Can you show me how?
– 4 Leave Cover
Nov 30 '18 at 7:20
|
show 1 more comment
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53460559%2fnested-loop-error-when-displaying-in-html-after-retrieve-from-api%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Try this
Logic:
this.http.post(url, options, headers)
.subscribe((data: any) => {
const categoryMap = data.products.reduce((categories, prod) => {
if (categories[prod.category]) {
categories[prod.category].push(prod);
} else {
categories[prod.category] = [prod];
}
return categories;
}, {});
this.categories = Object.keys(categoryMap).map(category => ({
category,
products: categoryMap[category]
});
}, (error: any) => {
console.log(error);
});
Template:
<ion-list *ngFor="let cat of categories | async">
<ion-list-header>
{{cat.category}}
</ion-list-header>
<ion-item *ngFor="let prod of cat.products | async"> <!-- not sure if async pipe is necessary here though -->
<ion-avatar item-start></ion-avatar>
<h2>haha{{prod.item.code}}</h2>
</ion-item>
</ion-list>
To clarify, the final structure of your data will look like this:
this.categories = [
{
category: "Beer Bottles",
products: [
{
item: {code: 'whatever'},
category: "Beer Bottles"
},
{
item: {code: 'something else'},
category: "Beer Bottles"
},
...etc.
]
},
{
category: "Beer Draught",
products: [ ...relevant products as above]
}
]
1
appreciated your effort. Let me have a look and get back soon.
– 4 Leave Cover
Nov 24 '18 at 19:44
Many thanks to you as it is working as expected now! Can I know why do we need have two category, one in outer and another one in products array? Btw I removed the async.
– 4 Leave Cover
Nov 25 '18 at 7:49
1
In this particular implementation, it would have been more trouble to try and remove the category from the individual products than it was worth for a Stack Overflow answer. You could certainly try to remove it, but it is probably not necessary.
– Ben Steward
Nov 25 '18 at 13:04
Indeed, I will probably do it in the future when I have more understanding on this part. Thanks a lot anyway :)
– 4 Leave Cover
Nov 25 '18 at 16:43
Hi Ben, for example I added a search bar. Can I implement the filter feature with this logic? The search bar can search for multiple fields e.g. code, desc, uom etc. Can you show me how?
– 4 Leave Cover
Nov 30 '18 at 7:20
|
show 1 more comment
Try this
Logic:
this.http.post(url, options, headers)
.subscribe((data: any) => {
const categoryMap = data.products.reduce((categories, prod) => {
if (categories[prod.category]) {
categories[prod.category].push(prod);
} else {
categories[prod.category] = [prod];
}
return categories;
}, {});
this.categories = Object.keys(categoryMap).map(category => ({
category,
products: categoryMap[category]
});
}, (error: any) => {
console.log(error);
});
Template:
<ion-list *ngFor="let cat of categories | async">
<ion-list-header>
{{cat.category}}
</ion-list-header>
<ion-item *ngFor="let prod of cat.products | async"> <!-- not sure if async pipe is necessary here though -->
<ion-avatar item-start></ion-avatar>
<h2>haha{{prod.item.code}}</h2>
</ion-item>
</ion-list>
To clarify, the final structure of your data will look like this:
this.categories = [
{
category: "Beer Bottles",
products: [
{
item: {code: 'whatever'},
category: "Beer Bottles"
},
{
item: {code: 'something else'},
category: "Beer Bottles"
},
...etc.
]
},
{
category: "Beer Draught",
products: [ ...relevant products as above]
}
]
1
appreciated your effort. Let me have a look and get back soon.
– 4 Leave Cover
Nov 24 '18 at 19:44
Many thanks to you as it is working as expected now! Can I know why do we need have two category, one in outer and another one in products array? Btw I removed the async.
– 4 Leave Cover
Nov 25 '18 at 7:49
1
In this particular implementation, it would have been more trouble to try and remove the category from the individual products than it was worth for a Stack Overflow answer. You could certainly try to remove it, but it is probably not necessary.
– Ben Steward
Nov 25 '18 at 13:04
Indeed, I will probably do it in the future when I have more understanding on this part. Thanks a lot anyway :)
– 4 Leave Cover
Nov 25 '18 at 16:43
Hi Ben, for example I added a search bar. Can I implement the filter feature with this logic? The search bar can search for multiple fields e.g. code, desc, uom etc. Can you show me how?
– 4 Leave Cover
Nov 30 '18 at 7:20
|
show 1 more comment
Try this
Logic:
this.http.post(url, options, headers)
.subscribe((data: any) => {
const categoryMap = data.products.reduce((categories, prod) => {
if (categories[prod.category]) {
categories[prod.category].push(prod);
} else {
categories[prod.category] = [prod];
}
return categories;
}, {});
this.categories = Object.keys(categoryMap).map(category => ({
category,
products: categoryMap[category]
});
}, (error: any) => {
console.log(error);
});
Template:
<ion-list *ngFor="let cat of categories | async">
<ion-list-header>
{{cat.category}}
</ion-list-header>
<ion-item *ngFor="let prod of cat.products | async"> <!-- not sure if async pipe is necessary here though -->
<ion-avatar item-start></ion-avatar>
<h2>haha{{prod.item.code}}</h2>
</ion-item>
</ion-list>
To clarify, the final structure of your data will look like this:
this.categories = [
{
category: "Beer Bottles",
products: [
{
item: {code: 'whatever'},
category: "Beer Bottles"
},
{
item: {code: 'something else'},
category: "Beer Bottles"
},
...etc.
]
},
{
category: "Beer Draught",
products: [ ...relevant products as above]
}
]
Try this
Logic:
this.http.post(url, options, headers)
.subscribe((data: any) => {
const categoryMap = data.products.reduce((categories, prod) => {
if (categories[prod.category]) {
categories[prod.category].push(prod);
} else {
categories[prod.category] = [prod];
}
return categories;
}, {});
this.categories = Object.keys(categoryMap).map(category => ({
category,
products: categoryMap[category]
});
}, (error: any) => {
console.log(error);
});
Template:
<ion-list *ngFor="let cat of categories | async">
<ion-list-header>
{{cat.category}}
</ion-list-header>
<ion-item *ngFor="let prod of cat.products | async"> <!-- not sure if async pipe is necessary here though -->
<ion-avatar item-start></ion-avatar>
<h2>haha{{prod.item.code}}</h2>
</ion-item>
</ion-list>
To clarify, the final structure of your data will look like this:
this.categories = [
{
category: "Beer Bottles",
products: [
{
item: {code: 'whatever'},
category: "Beer Bottles"
},
{
item: {code: 'something else'},
category: "Beer Bottles"
},
...etc.
]
},
{
category: "Beer Draught",
products: [ ...relevant products as above]
}
]
edited Nov 24 '18 at 18:11
answered Nov 24 '18 at 17:42
Ben StewardBen Steward
1,271616
1,271616
1
appreciated your effort. Let me have a look and get back soon.
– 4 Leave Cover
Nov 24 '18 at 19:44
Many thanks to you as it is working as expected now! Can I know why do we need have two category, one in outer and another one in products array? Btw I removed the async.
– 4 Leave Cover
Nov 25 '18 at 7:49
1
In this particular implementation, it would have been more trouble to try and remove the category from the individual products than it was worth for a Stack Overflow answer. You could certainly try to remove it, but it is probably not necessary.
– Ben Steward
Nov 25 '18 at 13:04
Indeed, I will probably do it in the future when I have more understanding on this part. Thanks a lot anyway :)
– 4 Leave Cover
Nov 25 '18 at 16:43
Hi Ben, for example I added a search bar. Can I implement the filter feature with this logic? The search bar can search for multiple fields e.g. code, desc, uom etc. Can you show me how?
– 4 Leave Cover
Nov 30 '18 at 7:20
|
show 1 more comment
1
appreciated your effort. Let me have a look and get back soon.
– 4 Leave Cover
Nov 24 '18 at 19:44
Many thanks to you as it is working as expected now! Can I know why do we need have two category, one in outer and another one in products array? Btw I removed the async.
– 4 Leave Cover
Nov 25 '18 at 7:49
1
In this particular implementation, it would have been more trouble to try and remove the category from the individual products than it was worth for a Stack Overflow answer. You could certainly try to remove it, but it is probably not necessary.
– Ben Steward
Nov 25 '18 at 13:04
Indeed, I will probably do it in the future when I have more understanding on this part. Thanks a lot anyway :)
– 4 Leave Cover
Nov 25 '18 at 16:43
Hi Ben, for example I added a search bar. Can I implement the filter feature with this logic? The search bar can search for multiple fields e.g. code, desc, uom etc. Can you show me how?
– 4 Leave Cover
Nov 30 '18 at 7:20
1
1
appreciated your effort. Let me have a look and get back soon.
– 4 Leave Cover
Nov 24 '18 at 19:44
appreciated your effort. Let me have a look and get back soon.
– 4 Leave Cover
Nov 24 '18 at 19:44
Many thanks to you as it is working as expected now! Can I know why do we need have two category, one in outer and another one in products array? Btw I removed the async.
– 4 Leave Cover
Nov 25 '18 at 7:49
Many thanks to you as it is working as expected now! Can I know why do we need have two category, one in outer and another one in products array? Btw I removed the async.
– 4 Leave Cover
Nov 25 '18 at 7:49
1
1
In this particular implementation, it would have been more trouble to try and remove the category from the individual products than it was worth for a Stack Overflow answer. You could certainly try to remove it, but it is probably not necessary.
– Ben Steward
Nov 25 '18 at 13:04
In this particular implementation, it would have been more trouble to try and remove the category from the individual products than it was worth for a Stack Overflow answer. You could certainly try to remove it, but it is probably not necessary.
– Ben Steward
Nov 25 '18 at 13:04
Indeed, I will probably do it in the future when I have more understanding on this part. Thanks a lot anyway :)
– 4 Leave Cover
Nov 25 '18 at 16:43
Indeed, I will probably do it in the future when I have more understanding on this part. Thanks a lot anyway :)
– 4 Leave Cover
Nov 25 '18 at 16:43
Hi Ben, for example I added a search bar. Can I implement the filter feature with this logic? The search bar can search for multiple fields e.g. code, desc, uom etc. Can you show me how?
– 4 Leave Cover
Nov 30 '18 at 7:20
Hi Ben, for example I added a search bar. Can I implement the filter feature with this logic? The search bar can search for multiple fields e.g. code, desc, uom etc. Can you show me how?
– 4 Leave Cover
Nov 30 '18 at 7:20
|
show 1 more comment
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53460559%2fnested-loop-error-when-displaying-in-html-after-retrieve-from-api%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
According to the error message, item is an object, not an array.
– Ben Steward
Nov 24 '18 at 17:37
how to make it become an array? But in console it is array, am I right? So weird
– 4 Leave Cover
Nov 24 '18 at 17:39
No, your second ngfor is entirely unnecessary. You’ve already begun to iterate over the array.
– Ben Steward
Nov 24 '18 at 17:40
I want all the items to be grouped in the category, if I only use 1 ngfor, the category will display as duplicate for every single item.
– 4 Leave Cover
Nov 24 '18 at 17:42
Ok, I see. I will update my answer in a minute.
– Ben Steward
Nov 24 '18 at 17:45