How to I use object based json data in Angular - json

//Employee service starts
import {
Injectable
} from "#angular/core";
import {
HttpClient,
HttpErrorResponse
} from "#angular/common/http";
import {
IEmployee
} from "../interfaces/employee";
import {
Observable
} from "rxjs/Observable";
import "rxjs/add/operator/catch";
import "rxjs/add/observable/throw";
#Injectable()
export class EmployeeService {
private _url: string = "assets/data/employee.json";
constructor(private http: HttpClient) {}
getEpmloyees(): Observable < IEmployee[] > {
return this.http.get < IEmployee[] > (this._url).catch(this.errorHandler);
}
errorHandler(error: HttpErrorResponse) {
return Observable.throw(error.message || "Server Error");
}
}
//Employee service end
//-------**********-------*********------**********-------
//Employee component starts
#Component({
selector: "app-employee-details",
templateUrl: "./employee-details.component.html",
styleUrls: ["./employee-details.component.scss"]
})
export class EmployeeDetailsComponent implements OnInit {
public employees = [];
public errorMsg;
constructor(private _employeeService: EmployeeService) {}
ngOnInit() {
this._employeeService.getEpmloyees().subscribe(
data => ((this.employees = data),
error => (this.errorMsg = error)
);
}
}
//Employee component ends
<p>{{errorMsg}}</p>
<table border="1">
<tr>
<th>ID</th>
<th>NAME</th>
<th>AGE</th>
<th>Mobile</th>
<th>Action</th>
</tr>
<tbody *ngFor="let employee of employees">
<tr>
<td>{{employee.id}}</td>
<td>{{employee.name}}</td>
<td>{{employee.age}}</td>
<td>{{employee.mob}}</td>
<td><button>Delete</button></td>
</tr>
</tbody>
</table>
<!--Used JSON data
[
{ "id": 1, "name": "sam", "age": 25, "mob": 9996663752 },
{ "id": 2, "name": "adward", "age": 26, "mob": 9124563712 },
{ "id": 3, "name": "yoshi", "age": 27, "mob": 9246663012 },
{ "id": 4, "name": "casie", "age": 29, "mob": 967663012 }
]
-->
<!-- This data through items object I want to use in above code
{
"items": [
{ "id": 1, "name": "harry", "age": 33, "mob": 3476643752 },
{ "id": 2, "name": "jorge", "age": 54, "mob": 7845633712 },
{ "id": 3, "name": "timon", "age": 65, "mob": 9753833012 },
{ "id": 4, "name": "simon", "age": 43, "mob": 8547763012 }
]
}
-->
Above is my Employee service code and employee's component which is working fine and so here also I have shared my JSON data on how I use second JSON data (which is below the first JSON data) and which is based on "items" object so I am in a situation that what changes do I need to get object base JSON data..?

Try with this.employees = data.items
ngOnInit() {
this._employeeService.getEpmloyees().subscribe(
data => ((this.employees = data.items),
error => (this.errorMsg = error)
);
}
}

Try creating a new interface for the Json data you're gonna retrieve.
interface RootObject {
items: IEmployee[];
}
In your service, get this RootObject and return it to your components.
public getEmployees(): RootObject {
return this.http.get<RootObject>(this._url).catch(this.errorHandler);
}
In your Employee Component, retrieve the array of IEmployees from "items" in the RootObject.
ngOnInit() {
this._employeeService.getEmployees().subscribe(
data => ((this.employees = data.items),
error => (this.errorMsg = error)
);
}
}
Be careful, you misspelled Employees in your service function. You might want to enable spell check in your IDE to avoid mistakes ;)

Related

recuperate fields of a json

I have a json like this :
[ {
"id": 1,
"libraryName": "lib1",
"bookName": "book1",
"bookPrice": 250.45,
"unitSold": 305
},
{
"id": 2,
"libraryName": "lib1",
"bookName": "book2",
"bookPrice": 450.45,
"unitSold": 150
},
{
"id": 3,
"libraryName": "lib1",
"bookName": "book3",
"bookPrice": 120.25,
"unitSold": 400
}]
I want to recuperate all the bookNames of this json in a list without creating the method getBookNames (because I want a standard way for any field of the json)
So, in the component.ts I used :
sales:any;
getSale () {
this.service.getSales().subscribe(data=> {this.sales = data,
console.log(this.sales.bookName)
})
}
It gives me undefined object in the console ! How can I solve this without creating a method getBookNames() ?
This is my class :
export interface Sale {
id: number
bookname : string
Libraryname: string
Bookprice : number
Unitsold : number
}
This is my service:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Sale } from './Sale';
#Injectable({
providedIn: 'root'
})
export class MyserviceService {
constructor(private http: HttpClient) { }
getSales () {
return this.http.get<Sale>("http://localhost:8081/sales/all")
}
}
The data obtained from the API is an array. So you could use array map() function to obtain a list of all the properties from the elements. Try the following
sales: any;
unitsSold = [];
getSale () {
this.service.getSales().subscribe(data=> {
this.sales = data,
console.log(data.map(item => item.bookName)); // <-- output: ['book1', 'book2', 'book3'];
console.log(data.map(item => item.id)); // <-- output: [1, 2, 3];
this.unitsSold = data.map(item => item.unitSold); // <-- [305, 150, 400]
});
}
I don't see anything lost here to recuperate.

Pushing json file into a localStorage array

I have a task to make CRUD app in angular 8 but I have to push somehow my JSON file into local storage and then be able to add new objects. I made an array of contacts and put some data in there and if someone can help me to put this JSON data in that array of objects, so I can read all my contacts from localStorage.
I have tried to subscribe to contacts and it kinda works but won't add data to a localStorage.
Contacts Service
import { Contact } from '../models/contact';
import { IContact } from '../models/contact';
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '#angular/common/http';
import { Injectable, OnInit } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class ContactService {
contacts: Array < Contact > = [{
first_name: "Darko",
last_name: "Lesevic",
emails: ["darko1#test.com", "darko2#test.com"],
phones: [123456789, 123456789, 123456789],
photo: ''
}];
constructor(private http: HttpClient) {
//this won't work
// this.getJSON().subscribe(data => {
// this.contacts = data;
// console.log(data);
// });
}
getJSON(): Observable < Contact[] > {
return this.http.get < Contact[] > ("/assets/data/contacts.json");
}
contacts_serialized: any;
contacts_deserialized: any;
localStorageObj() {
this.contacts_serialized = JSON.stringify(this.contacts); //converts data to string
localStorage.setItem('id', this.contacts_serialized);
this.contacts_deserialized = JSON.parse(localStorage.getItem('id')); //converts string to data
console.log(this.contacts_deserialized);
}
}
Calling contact Service here
import { ContactService } from '../services/contact.service';
import { Component, OnInit } from '#angular/core';
import { Observable } from 'rxjs';
import { Contact } from '../models/contact';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
constructor(private contactService: ContactService) { }
ngOnInit() {
this.contactService.localStorageObj();
}
}
MY JSON FILE
[{
"first_name": "Afonso",
"last_name": "Pinto",
"emails": ["mail01#gmail.com", "mail02#gmail.com"],
"phones": ["123-234-566", "123-234-567", "123-234-568"],
"photo": "http://lorempixel.com/400/300/people/"
},
{
"first_name": "Alexandre",
"last_name": "Paiva",
"emails": ["mail01#gmail.com"],
"phones": ["123-234-560", "123-234-561"],
"photo": null
},
{
"first_name": "Oea",
"last_name": "Romana",
"emails": ["mail01#gmail.com", "mail02#gmail.com"],
"phones": ["123-234-566", "123-234-567", "123-234-568"],
"photo": "http://lorempixel.com/400/300/people/"
},
{
"first_name": "Nuria",
"last_name": "Pelayo",
"emails": ["mail01#gmail.com", "mail02#gmail.com"],
"phones": ["123-234-568"],
"photo": "http://lorempixel.com/400/300/people/"
},
{
"first_name": "Lisandro",
"last_name": "Matos",
"emails": ["mail01#gmail.com", "mail02#gmail.com"],
"phones": ["123-234-566", "123-234-567"],
"photo": null
}
]
First of all, you need to subscribe and then use setItem
this.contactService.getJSON().subscribe((data) => {
localStorage.setItem('myData', JSON.stringify(data);
});

ERROR Error: Error trying to diff '[object Object]'. Only arrays and iterables are allowed

I have issue with nested JSON file. I use primeNG templates dataTable and treeTable. When I try to access data via API call in console I can see data but in template I'm getting this error:
ERROR Error: Error trying to diff '[object Object]'. Only arrays and iterables are allowed
json file
{
"CategoryId": "257cf663-f6ba-40f7-69b8-08d527528e70",
"Name": "House Only",
"OverBudgetCalculator": true,
"Scopes": [
{
"ScopeId": 1,
"Name": "Budget",
"Question": {
"QuestionId": 1,
"Content": "What is your maximum budget ?",
"QuestionType": "range",
"Strict": true,
"NeutralScore": 10,
"Weight": 100,
"UpDownSelectionApplied": false,
"Active": true,
"RelatedProductFields": [
{
"RelatedProductFieldId": 3,
"FieldName": "Budget",
"Step": 1000,
"Min": 0,
"Max": 0
}
],
"Answers": []
}
},
{
"ScopeId": 2,
"Name": "Levels",
"Question": {
"QuestionId": 2,
"Content": "Do you want a single or double ?",
"QuestionType": "singleSelection",
"Strict": true,
"NeutralScore": 10,
"Weight": 95,
"UpDownSelectionApplied": false,
"Active": true,
"RelatedProductFields": [
{
"RelatedProductFieldId": 10,
"FieldName": "House_Only_Levels",
"Step": 0,
"Min": 0,
"Max": 0
}
],
"Answers": [
{
"AnswerId": 18,
"Title": "Double Story",
"Content": "Double Story",
"MatchRule": "Double",
"UpDownSpecifications": [],
"Selected": false
},
{
"AnswerId": 19,
"Title": "Single Story",
"Content": "Single Story",
"MatchRule": "Single",
"UpDownSpecifications": [],
"Selected": false
}
]
}
scope.service.ts
import { Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from "#angular/http";
import { AppSessionService } from '#shared/common/session/app-session.service';
import { Observable } from 'rxjs/Observable';
import { Scope } from './scope';
import { TreeTableModule } from 'primeng/components/treetable/treetable';
#Injectable()
export class ScopeService {
constructor(
private http: Http,
private appSessionService: AppSessionService) { }
// GET api/categories/scopes/257CF663-F6BA-40F7-69B8-08D527528E70
getScopes(categoryId): Observable<any> {
let headers = new Headers({ 'Content-Type': 'application/json' })
let options = new RequestOptions({ headers: headers });
return this.http.get('/api/categories/' + categoryId)
.map((res: Response) => res.json())
.catch(this.handleErrorObservable);
}
private extractData(res: Response) {
let body = res.json();
return body.data || {};
}
private handleErrorObservable(error: Response | any) {
console.error(error.message || error);
return Observable.throw(error.message || error);
}
}
scope.component.ts
import { Component, Injector, OnInit, ViewChild } from '#angular/core';
import { AppComponentBase } from '#shared/common/app-component-base';
import { appModuleAnimation } from '#shared/animations/routerTransition';
import { ScopeService } from './scope.service';
import { DataTable } from 'primeng/components/datatable/datatable';
import { Paginator } from 'primeng/components/paginator/paginator';
import { TreeTableModule } from 'primeng/components/treetable/treetable';
#Component({
templateUrl: './scopes.component.html',
animations: [appModuleAnimation()]
})
export class ScopesComponent extends AppComponentBase implements OnInit {
errorMessage: String;
scopes: any = [];
categoryId: String = '257CF663-F6BA-40F7-69B8-08D527528E70';
constructor(
injector: Injector,
private scopeService: ScopeService
) {
super(injector);
}
ngOnInit(): void {
this.getScopes(this.categoryId);
}
getScopes(categoryId) {
this.scopeService.getScopes(categoryId).subscribe(values => {
this.scopes = values;
console.log(this.scopes);
})
}
}
This is component file with treeTable
scope.component.html (treeTable)
<p-treeTable [value]="scopes" [style]="{'margin-top':'50px'}">
<p-header>Editable Cells with Templating</p-header>
<p-column field="CategoryId" header="ScopeId">
<ng-template let-node="rowData" pTemplate="body">
<input type="text" [(ngModel)]="categories.Scopes.ScopeId" style="width:100%;border-width:0px 0px 1px 0px">
</ng-template>
</p-column>
<p-column field="Name" header="Name">
<ng-template let-node="rowData" pTemplate="body">
<input type="text" [(ngModel)]="categories.Scopes.Name" style="width:100%;border-width:0px 0px 1px 0px">
</ng-template>
</p-column>
</p-treeTable>
This is component file with dataDatable.
scope.components.html (dataTable)
<p-dataTable [value]="scopes"
selectionMode="single"
[rows]="10"
[responsive]="true">
<p-column field="Scopes" header="Scope name">
<ng-template let-account="rowData" pTemplate="body">
<ul>
<li *ngFor="let scope of categories.scopes">
{{scope.ScopeId}} - {{scope.Name}}
</li>
</ul>
</ng-template>
</p-column>
</p-dataTable>
When I use dataTable option I'm getting different error.
ERROR TypeError: val.slice is not a function
enter image description here
enter image description here

Angular map function is returning "undefined is not a function"

I'm following this tutorial https://www.barbarianmeetscoding.com/blog/2016/04/02/getting-started-with-angular-2-step-by-step-6-consuming-real-data-with-http/, with Angular2 and VS Code.
I created a db.json server to test an api with, with the test data looking like
{
"articles": [{
"id": 1,
"name": "Wand of Lightning",
"description": "A powerful wand of ligthning.",
"price": 50,
"imageUrl": "/assets/images/wand.png",
"specs": [{
"name": "weight",
"value": 10
}, {
"name": "height",
"value": 22
}, {
"name": "material",
"value": "wood"
}],
"reviews": [{
"author": "Jaime",
"title": "I loved it!",
"content": "I loved the wand of ligthning! I usually use it to charge my laptop batteries!",
"rating": 5
}, {
"author": "John Doe",
"title": "Underwhelming",
"content": "I didn't like it at all...",
"rating": 1
}]
}, {
"id": 2,
"name": "Staff of Fire",
"description": "A powerful staff of fire.",
"price": 150,
"imageUrl": "/assets/images/staff-of-fire.png",
"specs": [{
"name": "weight",
"value": 10
}, {
"name": "height",
"value": 22
}, {
"name": "material",
"value": "wood and alabaster"
}],
"reviews": [{
"author": "Jaime",
"title": "I loved it!",
"content": "I loved the wand of ligthning! I usually use it to charge my laptop batteries!",
"rating": 5
}, {
"author": "John Doe",
"title": "Underwhelming",
"content": "I didn't like it at all...",
"rating": 1
}]
}
Now if I try to adapt my code to the sample, I get
undefined is not a function
Here's items.component.ts
import { Component, OnInit } from '#angular/core';
import {ItemsService} from '../items.service';
import {Item} from '../item';
#Component({
selector: 'app-items',
templateUrl: './items.component.html',
styleUrls: ['./items.component.css']
})
export class ItemsComponent implements OnInit {
items: Item[] = [];
errorMessage: string = '';
isLoading: boolean = true;
constructor(private itemsService: ItemsService) { }
ngOnInit() {
this.itemsService
.getAll().
subscribe(
p => this.items =p,
e => this.errorMessage = e,
/* onCompleted */ () => this.isLoading = false
)
}
}
items.service.ts
import { Injectable } from '#angular/core';
import { Http, Response, RequestOptions, Headers } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import {Item} from './item';
#Injectable()
export class ItemsService {
private baseUrl: string ='http://localhost:3000';
constructor(private http: Http) {
}
getAll(): Observable<Item[]>{
let items = this.http
.get(`${this.baseUrl}/articles`, { headers: this.getHeaders()})
.map(this.mapItems)
.catch(this.handleError);
return items;
}
private getHeaders(){
let headers = new Headers();
headers.append('Accept', 'application/json');
return headers;
}
mapItems(response:Response): Item[]{
return response.json().map(this.toItem)
}
toItem(r:any): Item{
let result = <Item>({
id: r.id,
name: r.name,
description: r.description,
price: r.price,
imageUrl: r.imageUrl,
});
console.log('Parsed item:', result);
return result;
}
// this could also be a private method of the component class
handleError (error: any) {
// log error
// could be something more sofisticated
let errorMsg = error.message || `Yikes! There was a problem with our hyperdrive device and we couldn't retrieve your data!`
console.error(errorMsg);
// throw an application level error
return Observable.throw(errorMsg);
}
}
Note: making
return response.json().map(this.toItem)
Into
return response.json()
works. But I would like to get map working.
EDIT: Screenshot
this will solve your issue -
getAll(): Observable<Item[]> {
const items = this.http
.get(`${this.baseUrl}/articles`, {headers: this.getHeaders()})
.map((response: Response) => this.mapItems(response.json()))
.catch(this.handleError);
return items;
}
mapItems(data: Array<any>): Item[] {
return data.map(item => this.toItem(item));
}
I think what you want to map (Array.prototype.map) is the articles in your response object, and not the object itself. Do this:
mapItems(response:Response): Item[]{
return response.json().articles.map(this.toItem)
}

AngularJS 2 : Getting data from json file not working

I am trying to get the json data from an Angular service hero.service.ts. When using the fake http API inMemoryDataService, everything works fine and I am getting the json data from the in-memory-data.service.ts file. But when I try to get the data from a real json file, it does not work and I am getting an error 'collection not found' in the browser.
Here are the files contents (all 3 files are located in the app/ folder):
hero.service.ts :
import { Injectable } from '#angular/core';
import { Headers, Http , Response} from '#angular/http';
import 'rxjs/add/operator/toPromise';
import { Hero } from './hero';
#Injectable()
export class HeroService {
private heroesUrl = 'app/fakeListOfHeroes'; // URL to web api
//private heroesUrl = 'app/heroes.json'; // URL to JSON file
constructor(private http: Http) { }
getHeroes(): Promise<Hero[]>
{
return this.http.get(this.heroesUrl)
.toPromise()
.then(response => response.json().data)
.catch(this.handleError);
}
private handleError(error: any)
{
console.error('An error occurred', error);
return Promise.reject(error.message || error);
}
}
hero.service.ts :
export class InMemoryDataService {
createDb() {
let fakeListOfHeroes = [
{id: 11, name: 'Mr. Nice'},
{id: 12, name: 'Narco'},
{id: 13, name: 'Bombasto'},
{id: 14, name: 'Celeritas'},
{id: 15, name: 'Magneta'},
{id: 16, name: 'RubberMan'},
{id: 17, name: 'Dynama'},
{id: 18, name: 'Dr IQ'},
{id: 19, name: 'Magma'},
{id: 20, name: 'Tornado'}
];
return {fakeListOfHeroes};
}
}
heroes.json :
{
"data": [{
"id": 11,
"name": "Mr. Nice"
}, {
"id": 12,
"name": "Narco"
}, {
"id": 13,
"name": "Bombasto"
}, {
"id": 14,
"name": "Celeritas"
}, {
"id": 15,
"name": "Magneta"
}, {
"id": 16,
"name": "RubberMan"
}, {
"id": 17,
"name": "Dynama"
}, {
"id": 18,
"name": "Dr IQ"
}, {
"id": 19,
"name": "Magma"
}, {
"id": 20,
"name": "Tornado"
}]
}
Error in the browser:
error in browser
Any help would be appreciated. Thanks!
Found it ! It was due to the InMemoryBackendService and InMemoryDataService used in main.ts file, that seem to 'redirect' the calls from http.get method. Commenting those lines from main.ts file resolved the issue :
// Imports for loading & configuring the in-memory web api
import { XHRBackend } from '#angular/http';
//import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory-web-api';
//import { InMemoryDataService } from './in-memory-data.service';
// The usual bootstrapping imports
import { bootstrap } from '#angular/platform-browser-dynamic';
import { HTTP_PROVIDERS } from '#angular/http';
import { AppComponent } from './app.component';
import { appRouterProviders } from './app.routes';
bootstrap(AppComponent, [
appRouterProviders,
HTTP_PROVIDERS
/*,
{ provide: XHRBackend, useClass: InMemoryBackendService }, // in-mem server
{ provide: SEED_DATA, useClass: InMemoryDataService } // in-mem server data
*/
]);