How to read in Angular 2 the JSON #text - json

Sorry, but I'm stagnant to read a very specific JSON value in Angular 2&4, where I can obtain and showing the name of the list BUT! but I can't find a way to show in the page, what I'm talking about for example in the JSON document I have this way: (obtained from http://www.last.fm/api/show/artist.getTopAlbums ) and I'm using the Postman to check all the contents, I can obtain the name of the Album and other things, BUT to obtain the #text to use the image it's weird
"topalbums": {
"album": [
{
"name": "The Very Best of Cher",
"playcount": 1663904,
"mbid": "a7e2dad7-e733-4bee-9db1-b31e3183eaf5",
"url": "https://www.last.fm/music/Cher/The+Very+Best+of+Cher",
"artist": {
"name": "Cher",
"mbid": "bfcc6d75-a6a5-4bc6-8282-47aec8531818",
"url": "https://www.last.fm/music/Cher"
},
**// +++++++++++++++++++THIS PART +++++++++++++++++++++!!!!!**
"image": [
{
// I'M TRYING TO USE THIS INFORMATION
"#text": "https://lastfm-img2.akamaized.net/i/u/34s/287bc1657795451399d8fadf64555e91.png",
"size": "small"
},
{
"#text": "https://lastfm-img2.akamaized.net/i/u/64s/287bc1657795451399d8fadf64555e91.png",
"size": "medium"
},
{
"#text": "https://lastfm-img2.akamaized.net/i/u/174s/287bc1657795451399d8fadf64555e91.png",
"size": "large"
},
{
"#text": "https://lastfm-img2.akamaized.net/i/u/300x300/287bc1657795451399d8fadf64555e91.png",
"size": "extralarge"
}
]
},
What I want it's to obtain the "url" of the image, I try to obtain in this way:
artist.component.html
<div *ngFor="let list of albumes">
{{list.name}}
<hr>
<!-- Can't obtain the URL... -->
<img src="{{list.image[1].text}}" alt="">
</div>
artist.component.ts
import { Component, OnInit } from '#angular/core';
import {ActivatedRoute} from '#angular/router';
import {MusicService} from "../../services/music.service";
#Component({
selector: 'app-artist',
templateUrl: './artist.component.html',
providers: [MusicService]
})
export class ArtistComponent implements OnInit {
constructor(private service: MusicService, private route: ActivatedRoute) { }
albumes: any[];
songs: any[];
ngOnInit() {
this.route.params.map(params => params['mbid']).subscribe(
mbid => {
// Top Album
this.service.GetTopAlbumArtist(mbid).subscribe(topalbum => {
this.albumes = topalbum.topalbums.album;
console.log(topalbum.topalbums.image);
});
// Top Tracks
// this.service.GetTopTracksArtist(mbid).subscribe(toptracks => {
// this.songs = toptracks;
// });
}
)
}
}

First, if you want to get the first position of image array, you should access the position 0 (not 1)... also you don't have text but #text:
To solve your problem you can do this way:
src="{{list.image[0]['#text']}}"
or even better:
[src]="list.image[0]['#text']"

Related

How do I get my comments from local data.json to display on my page?

Trying to load the comments from my local json file but can't seem to get it to load properly. It's currently just showing a bulleted list of "0, 1, 2". Any ideas?
import React, { Component } from 'react'
import data from './../data'
class CommentList extends Component {
render () {
const elem = data.comments;
return (
<ul>
{Object.keys(elem).map(s => (<li>{s}</li>))}
</ul>
)
}
};
export default CommentList
{
"comments": [
{
"text": "Australian Shepherd!"
},
{
"text": "German Shepherd!"
},
{
"text": "Mutts all the way"
}
]
}
elem is an array so don't need Object.keys:
{elem.map(s => (<li>{s.text}</li>))}

How can I fetch a particular data from nested array from JSON file in Angular by using params?

This is my JSON file.
{mood:
[ {
"id":"1",
"text": "Annoyed",
"cols": 1,
"rows": 2,
"color": "lightgreen",
"route":"/angry",
"musics": [
{
"id": "0",
"name": "English- Heaven's Peace",
"image": "images/music.png",
"link": "https://www.youtube.com/playlist?list=PLPfXrbtn3EgleopO8DiEdsNKgqYZZSEKF",
"descpription": "Tunes that soothe your pained soul",
"reviews": [
{
"name": "abc",
"rating": 4,
"review": "energetic",
"date": ""
}
]
},
{
"id": "1",
"name": "English- Hell's Fire",
"image": "images/music.png",
"link": "https://www.youtube.com/playlist?list=PLPfXrbtn3EgmZitRQf1X1iYwWW_nUF44L",
"descpription": "Beats that match the ones of your heart",
"reviews": [
{
"name": "abc",
"rating": 3.5,
"review": "energetic",
"date": ""
}
]
},
{
"id": "2",
"name": "Hindi",
"image": "images/music.png",
"link": "",
"descpription": "",
"reviews": [
{
"name": "abc",
"rating": 4,
"review": "energetic",
"date": ""
}
]
},
{
"id": "3",
"name": "Punjabi",
"image": "images/music.png",
"link": "https://www.youtube.com/playlist?list=PLPfXrbtn3Egnntch2thUO55YqPQgo4Qh7",
"descpription": "",
"reviews": [
{
"name": "abc",
"rating": 4,
"review": "energetic",
"date": ""
}
]
},
{
"id": "4",
"name": "Mix and Match",
"image": "images/music.png",
"link": "https://www.youtube.com/playlist?list=PLPfXrbtn3EglN5LVTETqH3ipRLfXmY6MB",
"descpription": "",
"reviews": [
{
"name": "abc",
"rating": 5,
"review": "energetic",
"date": ""
}
]
}
]
} ]
}
I have created angular services in a file name mood.services.ts
import { Injectable } from '#angular/core';
import { Mood } from '../shared/mood';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
import { map, catchError } from 'rxjs/operators';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { baseURL } from '../shared/baseurl';
import { ProcessHTTPMsgService } from './process-httpmsg.service';
#Injectable({
providedIn: 'root'
})
export class MoodService {
constructor(private http: HttpClient,
private processHTTPMsgService: ProcessHTTPMsgService) { }
getMoods(): Observable<Mood[]> {
return this.http.get<Mood[]>(baseURL + 'moods')
.pipe(catchError(this.processHTTPMsgService.handleError));
}
getMood(id: number): Observable<Mood> {
return this.http.get<Mood>(baseURL+'moods/'+id)
.pipe(catchError(this.processHTTPMsgService.handleError));
}
getMoodIds(): Observable<number[] | any> {
return this.getMoods().pipe(map(moods => moods.map(mood => mood.id)))
.pipe(catchError(error => error));
}
getMusicIds(): Observable<number[] | any> {
return this.getMoods().pipe(map(musics => musics.map(music => music.id)))
}
}
And this is my musicdetail.component.ts file which will fetch the data of the particular music that is chosen.
import { Component, OnInit, Inject } from '#angular/core';
import { Mood } from '../shared/mood';
import { Music } from '../shared/music';
import { Review } from '../shared/review';
import { MoodService } from '../services/mood.service';
import { Params, ActivatedRoute } from '#angular/router';
import { Location } from '#angular/common';
import { switchMap } from 'rxjs/operators';
#Component({
selector: 'app-musicdetail',
templateUrl: './musicdetail.component.html',
styleUrls: ['./musicdetail.component.scss']
})
export class MusicdetailComponent implements OnInit {
mood : Mood;
music: Music;
musicIds: string;
errMess: string;
prev : string;
next : string;
review: Review;
constructor(private moodservice: MoodService,
private route: ActivatedRoute,
private location: Location,
#Inject('BaseURL') private BaseURL) { }
ngOnInit(): void {
this.route.params.pipe(switchMap((params: Params) => {return this.moodservice.getMood(params['id']);
}))
.subscribe(mood => {this.mood = mood;}, errmess => this.errMess = <any>errmess);
}
}
I have passed both mood.id and music.id when clicked in music.component.ts using '[routerLink]="['/musicdetails', mood.id, music.id]"`, on the list of music but I am unable to make logic to fetch particular music to display all its details. I am able to get mood-id using getMood(id) service but unable to do the same for music inside that mood.
WARNING:
your JSON data is wrong, Either you have missing single quote or double quote or 2nd bracket or third bracket. I don't know what you missed, its a long JSON file .
There is a JSON fixing website ( this one ) . I pasted your JSON and fixed it first.
Now I am writing this answer using correct version of your JSON (you can see it below)
So here it the answer:
The answer is simple - just use filter method to filter a particular property you need
.ts :
let jsonData =
{
"mood":[
{
"id":"1",
"text":"Annoyed",
"cols":1,
"rows":2,
"color":"lightgreen",
"route":"/angry",
"musics":[
{
"id":"0",
"name":"English- Heaven's Peace",
"image":"images/music.png",
"link":"https://www.youtube.com/playlist?list=PLPfXrbtn3EgleopO8DiEdsNKgqYZZSEKF",
"descpription":"Tunes that soothe your pained soul",
"reviews":[
{
"name":"abc",
"rating":4,
"review":"energetic",
"date":""
}
]
},
{
"id":"1",
"name":"English- Hell's Fire",
"image":"images/music.png",
"link":"https://www.youtube.com/playlist?list=PLPfXrbtn3EgmZitRQf1X1iYwWW_nUF44L",
"descpription":"Beats that match the ones of your heart",
"reviews":[
{
"name":"abc",
"rating":3.5,
"review":"energetic",
"date":""
}
]
},
{
"id":"2",
"name":"Hindi",
"image":"images/music.png",
"link":"",
"descpription":"",
"reviews":[
{
"name":"abc",
"rating":4,
"review":"energetic",
"date":""
}
]
},
{
"id":"3",
"name":"Punjabi",
"image":"images/music.png",
"link":"https://www.youtube.com/playlist?list=PLPfXrbtn3Egnntch2thUO55YqPQgo4Qh7",
"descpription":"",
"reviews":[
{
"name":"abc",
"rating":4,
"review":"energetic",
"date":""
}
]
},
{
"id":"4",
"name":"Mix and Match",
"image":"images/music.png",
"link":"https://www.youtube.com/playlist?list=PLPfXrbtn3EglN5LVTETqH3ipRLfXmY6MB",
"descpription":"",
"reviews":[
{
"name":"abc",
"rating":5,
"review":"energetic",
"date":""
}
]
}
]
}
]
} ;
// music - i can save here
let r = jsonData.mood[0].musics.filter(data => data.id == "2");
// music - or i can console.log it also
// i am comparing with 2 here - compare with your id number
// according to your need
console.log(jsonData.mood[0].musics.filter(data => data.id == "2"));
// in the same way you can search mood also
console.log(jsonData.mood.filter(data=> data.id == "1"));
to get something from parameter of url : follow this
there are multiple ways to get params from url
see this question : stackoverflow
see this blog : digitalocean

Check a recursive JSON structure for matchinig numerical values in Set in Typescript Angular

I have a UI where initially a User has to check some checkboxes. The checkboxes have sequential IDs. The JSON Structure for it is as follows:
{
"categories": [{
"name": "Product",
"labels": [{
"id": 1,
"name": "I work on an asset (capital good).",
"checked": false
}, {
"id": 2,
"name": "I work on a consumer product.",
"checked": false
}, {
"id": 3,
"name": "I am not sure what type of product I work on.",
"checked": false
}
]
}, {
"name": "Goal",
"labels": [{
"id": 4,
"name": "I want to improve the product's reliability.",
"checked": false
}, {
"id": 5,
"name": "I need information to identify root causes.",
"checked": false
}, {
"id": 6,
"name": "I need information about the product's environment.",
"checked": false
}, {
"id": 7,
"name": "I need information about customer requirements.",
"checked": false
}, {
"id": 8,
"name": "I need quantified information.",
"checked": false
}, {
"id": 9,
"name": "I am not sure what I need.",
"checked": false
}
]
}
]
}
I render it Angular using the following Code:
component.html
<div class="row mt-lg-auto" *ngFor="let filter of filters['categories']">
<div class="col-lg-12">
<h4>
{{filter['name']}}
</h4>
<div *ngFor="let label of filter['labels']">
<div class="form-check">
<input class="form-check-input"
type="checkbox"
value="{{label['id']}}"
id="{{label['id']}}"
[(ngModel)]="label['checked']"
(change)="changeCheck(label['id'], $event)"
>
<label class="form-check-label" for="{{label['id']}}">
{{label['name']}}
</label>
</div>
</div>
</div>
</div>
component.ts
I directly import the JSON file from src/assets/ folder and save the id to a Set in order to avoid duplicate values when the user selects a checkbox.
import { Component, OnInit } from '#angular/core';
import * as FilterFunc from 'src/assets/FilterFunction.json';
const Filters: any = FilterFunc;
#Component({
selector: 'explore-step1',
templateUrl: './explore-step1.component.html',
styleUrls: ['./explore-step1.component.css']
})
export class ExploreStep1Component implements OnInit {
filters = Filters.default;
selections = new Set();
constructor() {
}
ngOnInit(): void {
}
changeCheck(id: number, event: any) {
(event.target.checked) ?
this.selections.add(id):
this.selections.delete(id);
console.log(this.selections);
}
}
I am using ngx-treeview to render a tree view for a fixed JSON file that has the following structure:
GitHub Gist of the Complete Recursive JSON
Here on the children in the most depth have the following key-value pair:
"value": {
"label_ids": [relevant ids from the first json],
"description": "some text to render"
}
else the "value" is null.
I wish to compare the Set values to the above mentioned recursive JSON's label_ids and if one or more than one values in the label_ids match with the Set then change the checked value to true
How does one accomplish this in Typescript/Angular?
I solved it by creating a Recursion Parsing Function which takes in the JSON Structure.
Within the ngOnInit() I call the service and pass it to the parseTree function
I recursively parse it and compare the values with the Set
I add additional information like a Font-Awesome class text within the value structure to render it
pass the updated JSON to the respective items variable
component.ts:
parseTree(factors: TreeviewItem[]) {
factors.forEach(factor => {
// console.log(factor);
if (!isNil(factor.value)) {
let labels: number[] = factor.value['label_ids'];
labels.forEach(label => {
if(this.selected.findIndex(l => l == label) > -1) {
factor.value['highlighted'] = true;
factor.value['class'] = 'fas fa-flag';
}
});
}
if (!isNil(factor.children)) {
this.parseTree(factor.children);
}
});
this.items = factors;
}
here selections is a Set and within ngOnInit() I set it a fixed value:
ngOnInit() {
this.selections.add(15);
this.items = this.parseTree(this.service.getDataQualityFactors());
}
Based on ngx-treeview example I use the itemTemplate in the code and add the Font-Awesome fonts next to the selections as follows:
component.html
<label class="form-check-label" *ngIf="item.value !== null && item.value['highlighted']">
<i class="{{item.value['class']}}" aria-hidden="true" title="Highlighted" [ngClass]="{'marked': item.checked}"></i>
</label>
and use the CSS classes to manipulate the color change of the font:
.fa-flag {
color: red;
}
.fa-flag.marked {
color: green;
}
StackBlitz Example Code

How to get the length of JSON array?

I have a json url with a response of the following kind
[
{
"gender": "Female",
"age": 7,
"class": 2,
"subject": [
"",
"",
""
]
},
{
"gender": "Female",
"age": 8,
"class": 3,
"subject": [
"ab",
"cd",
"ef"
]
},
...
]
I want to find the length of this array
so in the angular app I am using
export class CustomComponent implements OnInit {
length: number;
constructor() {
this.length = Object.keys('www.url...').length;
console.log(length);
}
in .html I have
<p>{{ length }}</p>
I am getting 61 whereas the actual length is 44, but the console on the other hand is showing 0.
Where am I going wrong?
Any kind of help would be greatly appreciated. Thanks.
Easiest method.
import { Http } from '#angular/http';
export class CustomComponent implements OnInit {
length: number;
constructor(private http: Http){
this.http.request('www.url...',{method:'GET'}).map(response => response.json()).subscribe(result=>{
this.length=result.length;
});
}
}
Issue here is you are trying to execute Object.keys on url and not on
data , your url will be considered as string.
Solution is to use HttpClient :
// First get data from external url and then perform all operation
this.http.get('www.url...').subscribe(data => {
this.length = data.length;
console.log(length);
});

how to iterate and display multiple objects from json in angular 2?

I am new to code Angular 2. My question is how to show JSON Format A with a proper formatting. As shown, the result includes whole objects (named Atom) I want to display.
If JSON format looks like B, I can show it using ngFor well. However, in the Json format A, I have to create multiple Atom objects explicitly from result then I can show them using NgFor.
I do not have sufficient knowledge about Angular 2 and JSON, if you have some idea about this, could you give me some guide for this and which way could be desirable solution?
Json Format A
{
"pageS": 25,
"pageN": 1,
"pageC": 2,
"result": [
{
"type": "A",
"id": "2425",
"tree": "false"
},
{
"type": "A",
"id": "1185",
"tree": "false"
},
{
"type": "A",
"id": "2680",
"tree": "false"
},
]
}
Json Format B
[
{"type":"A", "id": "2425", "tree":"false"},
{"type":"A", "id": "1185", "tree":"false"},
{"type":"A", "id": "2680", "tree":"false"}
]
app.component.ts
import {Component} from 'angular2/core';
import {Router} from 'angular2/router';
import {AtomService} from './service/atom';
import {User} from './datatype/User';
#Component({
selector: 'my-app',
template: `
<ul>
<li *ngFor="#atom of atoms">
{{atom.id}}
</li>
</ul>
`,
providers: [AtomService]
})
export class AppComponent {
atoms: Array<Atom>;
constructor(private service : AtomService) {
service.getAtoms().subscribe(res => this.atoms = res);
}
}
atom.service
import { Injectable } from 'angular2/core';
import { Http, Response } from 'angular2/http';
import 'rxjs/add/operator/map';
import {Atom} from '../datatype/Atom';
#Injectable()
export class AtomService {
constructor(private http: Http) {
this.http = http;
}
getAtoms() {
return this.http.get('./app/api/atoms.json')
.map( (responseData) => {
return responseData.json();
})
.map((atoms: Array<any>) => {
let result:Array<Atom> = [];
if (atoms) {
atoms.forEach((atom) => {
result.push(new Atom(atom.type, atom.id, atom.tree));
});
}
return result;
});
}
}
I'm not sure I understand what exactly do you want. You can read the results directly from the response, if you don't want to iterate and create new Atom objects.
<ul>
<li *ngFor="#atom of data.result">
{{atom.id}}
</li>
</ul>
But I think the way you have it now is actually better, as you should process the data, even though you can bind HTML directly to the result.