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>))}
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
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
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);
});
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.