How to list objects in an object in html? - html

I'm writing app in Angular and Node.js. I have an object (order) that has a list of objects (items) that also contain objects (list of product id). I want to display them all in an html file. Please help me.
html file:
<div *ngIf="order">
<div *ngFor="let item of order.items"> // <- it does not work
<a>{{order.items}}</a> // <--
</div>
</div>
ts file:
export class AdminOrderItemComponent implements OnInit {
order: Order;
orderId;
constructor(private orderService: OrderService, private route: ActivatedRoute) { }
ngOnInit() {
this.route.paramMap
.subscribe(params => {
this.orderId = [params.get('id')];
this.getOrderById();
});
}
getOrderById() {
this.orderService.getOrderById(this.orderId).subscribe(
res => {
this.order = res;
},
err => console.log(err)
);
}
}
order interface:
export interface Order {
_id: any;
shipping: string;
userData: {};
sum: number;
items: {};
}

The ngFor iterates over the items of a collection. If you take a look at your model, you will realize that items is an object ({}), not an array ([]).
Your best bet is transforming the object received from your node.js backend to match your needs or (preferably I think) make your node.js model treat items as a collection as well which seems more appropriate.

Answer from #kg99:
Key: {{item.key}} and Value: {{item.value}}

Related

Json data not rendering my html grid table

I can't able to render my html grid table in angular using json data that is from mysql database.Please someone help me.
Output of the angular code
export class UserlistComponent implements OnInit {
users: Observable<User[]>;
constructor(private _service:NgserviceService, private _route:Router) { }
ngOnInit() {
this.reloadData();
}
reloadData(){
this.users = this._service.getUserList();
}
}
It seems you receive an array and not an object. You could simply map the received data and keep the rest.
reloadData() {
this.users = this._service.getUserList().pipe(
map(arrayUsers => arrayUsers.map(arrayUser => ({
id: arrayUser[0],
email: arrayUser[1],
firstname: arrayUser[2],
lastname: arrayUser[3],
})))
);
}
Your output seems to be CSV kind (array of an array) not the JSON. So, you need to use {{user[1]}} for email instead of {{user.email}} and {{user[2]}} for firstname instead of {{user.firstname}}

Assign Correctly json Object to class

I have a class with an interface :
from another component in the code I read a json of my list of hero, and want to create a class for each hero (so it is easier to manipulate their data)
MY shop list CLASS =>
interface ShopItemInterface {
name: string;
image: string;
price: number;
description: string;
}
export class ShopItem implements ShopItemInterface {
public name: string;
public image: string;
public price: number;
public description: string;
constructor(obj: object) {
for (let key in obj) {
// this doesn't work and I don't know why, it is always false
if (this.hasOwnProperty(key)) {
this[key] = obj[key];
}
}
}
}
LOADER COMPONENT CLASS =>
ngOnInit() {
this.http.get(this.jsonShopLocationFile).subscribe(res => {
for (let i = 0; i < res['items'].length; i++) {
this.shopItems.push(new ShopItem(res['items'][i]));
}
console.log(this.shopItems[0].name);
});
}
I can't find a way to correctly bind the json data to an object without listing all the parameters manually. ( which would be a mess and with 0 reusability)
How would you achieve that correctly ? Should I create a class and then directly call a function like hero.FromJSON(jsonObj) to manually set all the property? can I do this in some way in the constructor ?
thank you !
Because when you are constructing the object it does not have those properties, they are going to be undefined, just remove the test and it will work. Remember that interfaces are a TypeScript construct for the compiler and that you are running JavaScipt in your browser.
for (let key in obj) {
this[key] = obj[key];
}

How do i pass data received from angular to html front-end?

this is my angular service:
#Injectable()
export class ApiService {
private get_msg_url: string = "http://localhost:3000/getmessages";
constructor(private http:HttpClient) { }
getMessage(): Observable<IPosts> {
return this.http.post<IPosts>(this.get_msg_url,{"data":"data1"});
}
}
this is my message.component.ts :
export class MessagesComponent implements OnInit {
data = [];
iposts: IPosts[];
constructor(private apiSerivce: ApiService) {
}
getMessage(): void {
this.apiSerivce.getMessage()
.subscribe(data1 => this.data.push(data1));
}
ngOnInit(): void {
this.getMessage();
console.log(this.data);
}
}
this is my posts.ts:
export interface IPosts {
timestamp : number;
message_content : string;
message_link :string;
tags : string[] ;
}
this is messsage.component.html:
<p>Json data {{data}} </p>
whenever the code is run i can see the required data in console of chrome but there is no data shown on page.
the data received on console is of form:
[]
0:
message: Array(3)
0: {timestamp: 1522072833748,
tags: Array(2), _id: "5aacb7cc0281b558debacf26",
message_link:"String"
}}
the problem is, that you try to print an array, instead of the elements.
<p>Json data {{data}} </p>
change this to something like this:
<p *ngFor="let element of data; index as i">
Json data #{{i}}: {{element]]
</p>
As I can see, data is an array. you can display the raw content of an array with the pipe json : {{data | json}}
However I am not sur what you want to do with a json displayed in your html.
The problem is your output data is an array, not an element.
Try something like this,
<ul *ngFor="let element of data">
<li>{{element}}</li>
</ul>

Storing Objects inside Object in Arrays in Angular 2

I'm trying to store this data, given from a Wordpress Backend with HTTP Get Request in Ionic 2 (Angular 2).
I'm receiving this data structure,
Console Log of data response-
I'm trying to store this data like the menus (menu_1 and menu_2) in array of menus, the categories in array of categories, dishes in array of dishes...
How can I do that?
I don't want to show or iterate using Pipes, I only want to storage in Arrays to work easier with them.
My code at the moment is like:
home.ts:
I have a injectable class (Globals) to call the http get, but I do the subscribe in the getMenus function on my home.ts component:
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { Globals } from '../../providers/globals';
#Component({
selector: 'page-home',
providers: [Globals],
templateUrl: 'home.html'
})
export class HomePage {
menus: any;
constructor(public navCtrl: NavController, public globals: Globals) {
this.getMenus();
}
getMenus() {
this.globals.getMenus().subscribe(
data => {
console.log(data);
this.menus = data;
},
err => { console.log(err) }
);
}
}
And I have created a class, called Menu, at the moment is very simple:
import { Injectable } from '#angular/core';
import 'rxjs/add/operator/map';
#Injectable()
export class Menu {
name: any;
categories: any;
constructor() {
this.name = this.name;
this.categories = this.categories;
}
}
Where name is basic field of the object (key: name, value: "Today's menu" and categories is cat_1, cat_2 (two objects inside menu_1 object, which each contains more objects (dish_1, dish_2...).
My idea is create a class for every one of them, class Menu, class Category and class Dish. But I have any idea of how can I start store this objects in this classes. :S
Greetings!
The first thing to do is to create an interface for the data that you receive from the server, something like:
interface Dish {
Name: string;
Description: string;
Thumbnail: string;
}
interface Category {
[name: string]: Dish;
}
type ServerResponse = {
[name: string]: { [name: string]: Category; } & { name: string };
}
If you want to create classes from this data you can then:
class Menu {
name: string;
categories: { [name: string]: Category };
constructor(data: { [name: string]: Category; } & { name: string }) {
this.name = data.name;
this.categories = {};
Object.keys(data).forEach(name => {
if (name !== "name") {
this.categories[name] = new Category(data[name]);
}
});
}
}
(data: ServerResponse) => {
this.menus = {};
Object.keys(data).forEach(name => {
this.menus[name] = new Menu(data[name]);
});
}
You should also create the Category class and all, but that's the idea.
What are you trying to do ?
I think what you're trying to do is to normalize your data.
(Are you using a Redux pattern ? Maybe Ngrx ? If so, this is a great idea to normalize !)
Here's how a normalized state looks like : http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html
How should you do it ?
You can either do it by hand, which will become quite hard if you have many other requests to deal with, or you can describe your data in schema and use normalizr to do this job (normalizing data) for you.
If you don't know where to start. You can try this approach. First, create a model:
export class DummyModel {
menu: any;
cat: any;
dish: any;
...
//you can replace any with the type expected (string, number, etc)
}
In your component, you import your dummyModel and you set the data
import { DummyModel } from '../dummy.model';
/...
dummyModel: DummyModel = dummyData;
Also, consider #Nitzan Tomer advise, try to write your code and people here can help if you are facing an issue

How do I pass data from a json file into a html file in Angular 2?

I have this files.
wordCloud.ts
export class HomePageComponent {
wordcloudData : Array<string>;
private searchField : string;
private wordsApi : string;
wordClouds: any[] = [];
errorMessage: string;
listId:any = 1;
#Input() data : any;
#Input() testProperty : any;
#Input() dataField : string;
#Input() apiUrl : string;
constructor(public wordCloudListService: LexiconListService) {}
getWordCloudList() {
this.wordCloudListService.get('/assets/adhoc-search.json')
.subscribe(
wordClouds => {
EmitterService.get(this.listId).emit(wordClouds);
},
error => this.errorMessage = <any>error
);
}
ngOnInit() {
this.getWordCloudList();
EmitterService.get(this.listId).subscribe((wordClouds:any) => {this.wordClouds});
}
}
wordCloud.html
<div class="center" style="margin: 0 auto; width: 30%; padding-top: 100px;">
<cst-word-cloud [data]="{{wordClouds}}"></cst-word-cloud>
</div>
As you can see, I'm trying to load a json data and display the data into the wordCloud hmtl. I'm currently having difficulties doing this? Is there anything I'm doing wrong? How do I pass the value in the wordClouds array to display it?
In your ngOnInit() you are not getting the data of wordClouds in this.wordClouds.. just do this.
ngOnInit() {
this.getWordCloudList();
EmitterService.get(this.listId)
.subscribe((wordClouds:any) => {
this.wordClouds = wordClouds;
});
}
Do not emit the data. First of all is emitting a data is not the right approach. You should always emit the states like Boolean values or data which is used for a temporary basis. I would prefer not emitting the data, instead store first. Store it in some dataStore/ Class file. Make a class and store the data in it. After storing bind the template from that class getter method.