I am developing an static website with angular, we've decided to put data in JSON files. But data is quite large and repetitive in nature.
So, I've decided to segregate data in multiple JSON files.
Like
foo.json
{ name: 'Avinash', Age: 88 }
Woo.json
{ City: 'Newyork', Street: 'Lincoln Park' }
Soo.Json
{City: 'Dubai', Street: "Marina"}
Loo.Json
{ Customer: 'foo.json', Address1: 'Woo.json', Address2: 'Soo.Json' }
It should compile all objects to gether on retrieval.
I've read json pointers concept here, thought it might be useful. But I don't know how to do it in Typescript...
Instead of json files, create ts files and export const from there. Something like this:
foo.ts
export const foo = { name: 'Avinash', Age: 88 };
woo.ts
export const woo = { City: 'Newyork', Street: 'Lincoln Park' };
soo.ts
export const soo = {City: 'Dubai', Street: "Marina"};
loo.ts
import { foo } from './foo';
import { woo } from './woo';
import { soo } from './soo';
export const loo = { Customer: foo, Address1: woo, Address2: soo };
loo will contain an aggregated object that you can then import and use in the Component you want.
Something like this:
import { Component } from '#angular/core';
import { loo } from './data/loo';
#Component({...})
export class AppComponent {
ngOnInit() {
console.log(loo);
}
}
Related
In def.js:
export const defs = {
name: 'Joe',
age: 30,
id: 123
}
In user.js:
import { defs } from './def';
const { name } = defs;
console.log(name);
Is there a way to import defs.name right away, without importing defs first?
Something like:
import {defs.name} from './defs';
I'm trying to build an app with ionic that reads data from a local `.json' file and uses this data to fill a page. But I'm already struggling with importing the file into the page. What I currently have is:
import { Component } from "#angular/core";
interface Entry {
name: string,
telephone: string
}
interface EntryList {
entryList: Array<Entry>;
}
#Component({
selector: 'page-list',
templateUrl: 'list.html'
})
export class ListPage {
entryList: EntryList;
constructor() {
this.load_entries();
};
load_entries () {
this.entryList = JSON.parse(
// ?
)
};
}
The .json file contains entries like:
[
{"name": "Person A","telephone": "1234"},
{"name": "Person B","telephone": "12345"}
]
I don't know how to proceed from here on. What's the right way to get my data into the app?
Please try this:
constructor(public http: HttpClient) {
this.load_entries();
};
load_entries(filePath: string) { //filePath: 'assets/test.json'
this.http
.get(filePath)
.subscribe((data) => {
console.log(data);
});
}
Of course, you have to import HttpClient first.
import { HttpClient } from '#angular/common/http';
I want to display a line chart from JSON data. I have used angular2-highcharts. The problem is that the chart is displayed without data. I think that the issue is from extracting data from JSON.
The JSON format looks like this:
[{"_id" : ObjectId("59049a7b223f1e21ee4ee23b"),"amount" : 1,"date" :
"Mon, 18 Dec 1995 18:28:35 GMT"},{"_id" :
ObjectId("59049a7b223f1e21ee4ee23b"),"amount" : 1,"date" : "Mon, 18
Dec 1995 19:28:35 GMT"}]
I need only the "amount" in the X value and the "date" in the Y value.
Here is my code
ChartistJs.service.js
import {Injectable} from '#angular/core';
import { Headers, Http, RequestOptions, Response } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { Data } from "./Data";
import 'rxjs/add/operator/toPromise';
private Url ='http://localhost:3000/transfer/chart';
constructor (private http: Http) {}
getData(){
return this.http.get(this.Url)
.toPromise()
.then(response => response.json())
.catch(this.handleError);
}
ChartistJs.component.ts
import {Component} from '#angular/core';
import {ChartistJsService} from './chartistJs.service';
import 'style-loader!./chartistJs.scss';
import { Observable } from "rxjs/Observable";
import { ChartModule } from 'angular2-highcharts';
import 'rxjs/Rx';
import {Observer} from 'rxjs/Observer';
import {Http, Jsonp} from '#angular/http';
#Component({
selector: 'chartist-js',
template: `
<chart [options]="options"></chart>
`,
providers : [ChartistJsService]
})
export class ChartistJs {
options: Object;
constructor(private _chartistJsService:ChartistJsService) {
var chartData = this._chartistJsService.getData();
this.options = {
title : { text : 'simple chart' },
xAxis: {
type: 'category'
},
series: [{
data: chartData
}]
};
}
}
Can you help me how to deal with JSON data in Angular 2?
As Pankaj points out you are trying to pass a promise as the data, not the actual data that the promise eventually resolves to. More broadly, though, you aren't really using the tooling that Angular provides for dealing with HTTP.
In general, I would recommend that you:
Get used to dealing with observables, which is what Angular uses natively, rather than converting everything back to promises (although I think they still show this in the docs); and
Lean into the asynchronous nature of the observables, using the AsyncPipe to resolve them into your templates and the objects that RxJS provides to manipulate the data flow.
More specifically, here's one way you could implement what you're currently trying to.
Service:
#Injectable()
class DataService {
// acts as a pipe for the data that you can push new items into
private dataSubject = ReplaySubject(1);
// takes the subject and exposes the result, read-only
chartData$ = this.dataSubject.asObservable();
constructor (private http: Http) {}
getData() {
// GETs the data and pushes it into the subject
this.http.get('http://localhost:3000/transfer/chart')
.map(response => response.json())
.subscribe(data => this.dataSubject.next(data));
}
}
Component:
#Component({
... ,
// resolves the chart options asynchronously in the template
template: `
<chart [options]="chartOptions$ | async"></chart>
`
})
export class MyChartComponent implements OnInit {
chartOptions$: Observable<any>;
constructor(dataService: DataService) {
// creates a new observable of the chart options
this.chartOptions$ = this.dataService.chartData$
.map(data => this.createChartOptions(data));
}
ngOnInit() {
// triggers a fetch of the data to feed the observable
this.dataService.getData();
}
private createChartOptions(data) {
return {
title: { text: 'simple chart' },
xAxis: { type: 'category' },
series: [{ data: data }],
};
}
}
You will probably need to do more to the JSON than just pass it as the series.data, but this hopefully gives you an idea of how to leverage the stream of events an observable can provide. I've written more about this on my blog, including a follow-up article on testing.
Also note that your components shouldn't be importing anything from '#angular/http' - leave that to the services, use them as a layer of abstraction from the source of the data - and you can load providers at the module, rather than component, level.
Actually chartData variable does hold Promise returned by getData method. Where you should keep .then over the getData method calla and assign options with chartData like shown below.
It would be more better if you can do the same in ngOnInit lifecycle event.
Code
export class ChartistJs {
options: Object;
constructor(private _chartistJsService: ChartistJsService) {}
ngOnInit() {
this._chartistJsService.getData().then(
(data) => {
this.options = {
title: {
text: 'simple chart'
},
xAxis: {
type: 'category'
},
series: [{
data: data
}]
};
}
);
}
}
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
I've cloned tour of heroes tutorial product from angular team where demo data is storing in in-memory-data-service.ts. Since my preferred backend is django-rest-framework, I need to link them together.
For example, my heroes are translating from localhost:8000/api/v1/heroes/.
[
{
"name": "Greg",
"id": 5,
},
{
"name": "Krek",
"id": 6,
}
]
What should I do except removing in-memory-data-service.ts to replace heroes list with provided by django backend via json? It would be great if you'll tell me do I need model declaration
export class Hero {
id: number;
name: string;
}
yet if rest-framework gives me full objects structure stored in JSON.
To consume any REST API you have to write a service like below,
import { Injectable } from 'angular2/core';
import { Http, Response } from 'angular2/http';
import { Observable } from 'rxjs/Rx';
export class Hero {
id: number;
name: string;
}
#Injectable()
export class HeroService {
constructor(private _http: Http) { }
getHeroes() {
return this._http.get('api/v1/heroes')
.map((response: Response) => <Hero []>response.json())
}
}
Hope this helps!!