I want to display content from the firebase I get the data from HTTP get request and I want to display it using ngFor
here is how i get the data
///a service
getMessages(){
return this.http.get('https://bigproject-dd88e.firebaseio.com/data.json')
.map((response:Response)=>{
const data: Message[]=response.json();
return data;
}
).catch(
(error:Response)=>{
return Observable.throw('something went wrong');
}
);
}
and here is my component
export class MessagesComponent implements OnInit {
Message=[];
constructor(private global:GlobalService) {
}
ngOnInit() {
this.GenaerateMessages();
}
GenaerateMessages(){
this.global.getMessages().subscribe(
Message=>this.Message=Message
);
}
}
and here is my HTML
<div *ngFor="let item of Message | keyvalue">
<p>{{item.value|json}}</p>
</div>
I get this on the screen
[ { "email": "loay-gohan#hotmail.com", "message": "loayy", "name": "loay", "phone": "123123123" } ]
[ { "email": "example#example", "message": "hi", "name": "..", "phone": "123123" } ]
how can I reach the inside fields name, message, phone...
it looks like eachitem.value contains one array with one object. If this is a case you can reach it like this:
<div *ngFor="let item of Message | keyvalue">
<div>EMAIL: {{ item.value[0].email }}</div>
<div>MESSAGE: {{ item.value[0].message }}</div>
<div>NAME: {{ item.value[0].name }}</div>
<div>PHONE: {{ item.value[0].phone }}</div>
<pre>{{ item.value | json }}</pre>
</div>
If item.value array has more than one object you might want to loop it wit additional inner ngFor
You do not use value.key. Don't you need it?
Related
I am trying to display the currency name or key like "USD", "AUD", "EUR" with their respective "last" and "buy" properties from this HTTP response:
and I just get back a list of "key" strings like this
but I can't figure out why my "key" is being returned as a string here.
It's making it difficult for me to programmatically access the properties for each currency
this is my dashboard.component.ts
prices;
bitcoinOwned;
ngOnInit(): void {
this.data.getPrice()
.pipe(map(result => {this.prices = result, console.log("result", result)
for (let key in result) {console.log( key)}
} ))
.subscribe();
}
my data.service
getPrice() {
var url = "https://blockchain.info/ticker";
return this.http.get(url);
}
and my template
<div>
{{ prices |json }}
</div>
<div>
USD last: {{ prices?.USD.last |json }} USD sell: {{ prices?.USD.sell |json }}
</div>
I can access the properties when I do it manually for each key like this but I need to iterate over the keys and do it more programmatically so any help would be appreciated!!
You may want to use Angular's KeyValuePipe.
Then, you can do something like this:
<div *ngFor="let item of prices | keyvalue">
{{item.key}} last: {{ item.value.last |json }} {{item.key}} sell: {{ item.value.sell |json }}
</div>
I think you can use Object.keys() on the object to return the key value.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
Angular2 Unable to print JSON Nested array
help me with nested array problem. Unable to print User_name, User_id and User IRN..
My Component.ts
this.apiService.getIM().subscribe((getIM) => {
this.iOverview = getIM['message'];
console.log(this.iOverview); //This print the whole array.
});
HTML Code
<tr *ngFor="let iUsers of iOverview?.response?.i_details?.user_details | slice:0:10;">
<td>
<div>
<a href="javascript:void(0)"
class="text-default font-weight-semibold letter-icon-title">{{ iUsers.user_name }}</a>
</div>
</div>
</td>
</tr>
My Json Output
{
"message": {
"response": {
"res_type": "IM Users", //able to print this value
"acc_id": "1234567890",
"i_details": [
{
"user_details": [
[
{
"user_name": "admins", //not able to print this value.
"user_id": "MyGroups1",
"user_arn": "user:763526717345"
}
]
]
}
]
}
}
}
Have you noticed that the properties you are trying to access are nested in another array? "user_details": [[...]]. Try accessing it like this:
*ngFor="let iUsers of iOverview?.response?.i_details?.user_details[0]
Hope it helps!
JSON Data:
"abcd":[
{
"id":"1",
"cityId":"2",
},
{
"id":"2",
"cityId":"3",
}
],
"city":[
{
"id":"2",
"cityName":"california"
},
{
"id":"3",
"cityName":"vicecity"
}
]
Angular:
<div *ngFor="let clg of abcd$">
<p>
{{clg.cityId}}
<!-- Here i need to print the cityname from city by using the cityId we have got from abcd -->
</p>
</div>
app.component.ts:
ngOnInit() {
this.data.getColleges().subscribe(
data => this.abcd$ = data
)
}
fetching data from "abcd" is perfectly working....and no problem in fetching the datas from "city" too. But is it possible to fetch the cityName from "city" by using the cityId key from the "abcd" section.
You can use a method to get city by ID:
app.component.ts:
getCityByID = (cityID) => {
return this.city$.find(item => item.id === cityID);
}
Template:
<div *ngFor="let clg of abcd$">
<p>
{{ clg.cityId }}
{{ getCityByID(clg.cityId).cityName }}
</p>
</div>
Update
As far as I understand, you are fetching colleges and cities with 2 separate observables. Because of this, when you are trying to get city by ID, it may (or may not) throw an error if second observable has not been resolved yet. So, you need to combine/join these two streams together. I prefer combineLatest to do this but forkJoin will work as well.
In app.component.ts:
import { combineLatest } from 'rxjs';
......
ngOnInit() {
combineLatest(
this.data.getColleges(),
this.data.getCity()
).subscribe(([colleges, cities]) => {
this.abcd$ = colleges;
this.city$ = cities;
});
}
This way, you make sure that both abcd$ and city$ are inited. Hope this helps.
For further reading:
combineLatest: https://www.learnrxjs.io/operators/combination/combinelatest.html
forkJoin: https://www.learnrxjs.io/operators/combination/forkjoin.html
I am having trouble displaying data from querying an API endpoint. The error message is ERROR TypeError: Cannot read property 'name' of undefined. I understand that I have to jump to display the "matches" array but having a lot of difficulty doing so.
This is what the url returns:
{
"query": "An",
"matches": [
{"name": "Jane Hardman", "id": "248086622848468681706182205280565550732"},
{"name": "Gary Aldan", "id": "246529435182620212343890064029443600078"}
]
}
This is my meeting-handler.service.ts file:
constructor(private _httpClient: HttpClient) {}
getListOfEmployees(query: string = '') {
return this._httpClient.get(
`${this.meetingUrl}/employees?q=${query}`);
}
This is my meeting-form.component.ts file:
export class MeetingFormComponent implements OnInit {
employees;
constructor(private _meetingService: MeetingHandlerService) {
this._meetingService.getListOfEmployees('An').subscribe(
res => this.employees = res
)
}
And finally this is my meeting-form.component.html file:
<div *ngFor="let employee of employees"></div>
<p>{{ employee.name }}</p>
The name is inside this.employees.matches and you have to iterate on the matches field.
Can you try this :
<div *ngFor="let employee of employees?.matches.name"></div>
<p>{{ employee }}</p>
Can you try to edit your get request ?
return this.http.get(`${this.meetingUrl}/employees`, {
params: new HttpParams()
.set('q', query)
})
I checked your stackblitz and I found a typo here :
<div *ngFor="let employee of employees?.matches.name"></div>
<p>{{ employee.name }}</p>
Why are you using {{ employee.name }} ? You iterate on name so you employee is already a name.
Try this :
<div *ngFor="let name of employees?.matches.name"></div>
<p>{{ name }}</p>
<div *ngFor="let employee of employees">
<p>{{ employee.name }}</p>
</div>
Moved the closing tag.
I have been trying to display a json file having multiple arrays in it on the front-end div tag in using Services Angular2 using Typescript. Can anyone help?
Also, If anyone can help transforming this code by adding Model and Interface class would be very helpful.
Here is the code:
SERVICE
export class HttpServiceDemo{
_data: any;
private url: string = "assets/sample.json"
constructor(private http: Http){}
getMyOrder(){
//return this.http.get(this.url)
// .map((response: Response)=> response.json());
return this.http.get(this.url)
.map(res => this.http = res.json().myOrder);
}
}
component.ts
export class SimpleHTTPComponentComponent implements OnInit {
data:any;
Order_date:any;
OrderNumber: number;
P_O_Number:number;
Total: number;
Quote_Status: string;
Expiration_Date: any;
Quote_Created_On: any;
constructor(public vara: HttpServiceDemo) {
}
ngOnInit() {
//calling myorder from json
this.vara.getMyOrder().subscribe(response => {
this.data=response;
for (var myOrder in this.data)
{
console.log(myOrder, this.data[myOrder]);
this.Order_date=this.data[myOrder].Order_Date;
this.OrderNumber=this.data[myOrder].OrderNumber;
this.P_O_Number=this.data[myOrder].P_O_Number;
this.Total=this.data[myOrder].Total;
this.Quote_Status=this.data[myOrder].Quote_Status;
}
})
}
sample.json
---------------
{
"accOrder":[
{
"Order_Date": "10-sep-1981",
"OrderNumber" : "E12345",
"P_O_Number": "P12345",
"Total": "123",
"Quote_Status": "In Progress"
},
{
"Order_Date": "1-oct-1981",
"OrderNumber" : "E82398",
"P_O_Number": "P87815",
"Total": "265",
"Quote_Status": "In Progress"
},
{
"Order_Date": "21-nov-1981",
"OrderNumber" : "E52367",
"P_O_Number": "P76549",
"Total": "454",
"Quote_Status": "In Progress"
},
{
"Order_Date": "10-dec-1981",
"OrderNumber" : "E42840",
"P_O_Number": "P23632",
"total": "123",
"Quote_Status": "Completed"
}
]
}
You are saying your console.log() shows the JSON just fine ?
Then, your data is correctly fetched into your component's data attribute.
You just have to go through your attribute in your template using *ngFor directive then.
Plunkr : https://plnkr.co/edit/4IdV3OHyNFNi90KXQQHP?p=preview
template: `
<div>
<div *ngFor="let order of data.accOrder" style="border: 1px solid lightgrey; padding: 15px; margin: 5px 0;">
Order_Date : {{ order.Order_Date }} <br>
OrderNumber : {{ order.OrderNumber }} <br>
P_O_Number : {{ order.P_O_Number }} <br>
Total : {{ order.Total }} <br>
Quote_Status : {{ order.Quote_Status }} <br>
</div>
</div>
`
PS : No need for your "for" loop inside ngOnInit() , this is not how you should access the data.
You should check out the ngFor doc to learn more about it.
EDIT :
As I said in my comment below, my previous Plunker was using raw data while you use asynchronous data in your use case (it's coming from an Observable sent from your service).
To make it work then, you have to check if your component already received the data before you try to display it. For that, you need to use the *ngIf directive.
New Plunkr : https://plnkr.co/edit/W5qykrh4blplGxTyp8aC?p=preview
template: `
<div *ngIf="data; else loading">
<div *ngFor="let order of data.accOrder" style="border: 1px solid lightgrey; padding: 15px; margin: 5px 0;">
Order_Date : {{ order.Order_Date }} <br>
OrderNumber : {{ order.OrderNumber }} <br>
P_O_Number : {{ order.P_O_Number }} <br>
Total : {{ order.Total }} <br>
Quote_Status : {{ order.Quote_Status }} <br>
</div>
</div>
<ng-template #loading>Fetching the data from the webservice... Wait 3 seconds !</ng-template>
`,
You have to create a parent div to the one with your *ngFor directive. In this parent div, use the *ngIf="data" directive. Everything inside it will not be displayed until there is some data into the data attribute.
I used here an if/else syntax which appeared with Angular4. But you don't need that. That's just here to display a message while there is no data. It could be a loading spinner for example, to let the user know he has to wait.
If you don't want to use this if/else condition, you can do it without it like that :
template: `
<div *ngIf="data">
<div *ngFor="let order of data.accOrder" style="border: 1px solid lightgrey; padding: 15px; margin: 5px 0;">
Order_Date : {{ order.Order_Date }} <br>
OrderNumber : {{ order.OrderNumber }} <br>
P_O_Number : {{ order.P_O_Number }} <br>
Total : {{ order.Total }} <br>
Quote_Status : {{ order.Quote_Status }} <br>
</div>
</div>
`,
Hope this helped :)