Plotting JSON data with angular2-highchart - json

I want to plot data in a JSON file using angular2-highcharts.
Let's say there are X and Y values in the JSON file in the following format:
[[[1,15],[2,16],[3,18]]]. The code is as follows.
#Component({
selector: 'my-app',
directives: [CHART_DIRECTIVES],
template:`{{sample}}
<center> <chart [options]="options"></chart></center>`
})
export class AppComponent {
public sample;
options:Object;
constructor(public http : Http) {
http.get('data.json')
.map(res => res.json())
.subscribe(data =>this.sample=JSON.parse(JSON.stringify(data || null)),
err=>console.log(err),
() => console.log('Completed')); {}
console.log(this.sample);
this.options = {
title : { text : 'Sample Curve' },
series: [
{ data: this.sample,
color:'red'},]
}
}
}
I get the values of data in the .json file and display it as a part of the template and the correct values seem to get printed. However, my highchart plot is empty. Since i am equally new to Javascript and typescript, I probably am not making full use of some answers here already.

You are trying to implement simple line chart.
Line Chart expects data to be in this formats-
[29.9, 71.5, 106.4, 129.2] or [[1,15],[2,16],[3,18]]
whereas your json structure is in this format
[[[1,15],[2,16],[3,18]]]
You can try like this-
Import JSONP_PROVIDERS-
import {JSONP_PROVIDERS, Jsonp} from '#angular/http';
providers: [JSONP_PROVIDERS],
In html template-
<chart [options]="options1"></chart>
In your component-
options1: Object;
constructor(jsonp : Jsonp) {
jsonp.request('https://www.highcharts.com/samples/data/jsonp.php?filename=aapl-c.json&callback=JSONP_CALLBACK').subscribe(res => {
this.options1 = {
title : { text : 'AAPL Stock Price' },
series : [{
name : 'AAPL',
data : res.json(),
tooltip: {
valueDecimals: 2
}
}]
};
});
See if this helps.

Okay, so, the options for the chart component needs to be set within the subscribe method as in the above example Sanket has posted. I was not giving it within subscribe. The value stored in this.sample goes back to what it was initialized to once outside the subscribe method.I still don't understand why the values get printed correctly in the template portion though.

Related

How to define a state with JSON data (using react and axios)

I am a little confused about how to go about this. So I have this JSON file called posts.json.
[
{
"id": 1,
"title": "Kylie Jenner",
"content": "Social Media Public Figure",
"disclaimer": "*Disclaimer: This user may have comment filtering turned on",
"slug": "hello-world",
"img" : "https://ilarge.lisimg.com/image/16801290/1080full-kylie-jenner.jpg",
"banner" : "https://i.pinimg.com/originals/a5/2b/96/a52b963809c7e64e538b113cccf61dda.jpg",
"handle": "kyliejenner",
"handlelink" : "https://www.instagram.com/kyliejenner/"
}
]
I am currently trying to make a GET request to an API(url) that also includes specific data from my json file. In this case it will include the celebs handle. This is what I have setup here on Graphs.js.
export default class Graph extends Component {
constructor(props) {
super(props);
}
state = {
handle: '',
}
componentDidMount() {
axios.get('http://localhost:5000/celebs/' + handle)
.then(response => {
this.setState({ celebs: response.data })
})
.catch((error) => {
console.log(error);
})
}
}
I am aware this isn't right as this is where I am stuck. "+ handle" is to come from the json file. I want to make a request to the url where /handle will match the handle directly from json file as defined "handle": "#kyliejenner". But I keep getting an error saying 'handle' is not defined no-undef. No matter how I do it, I can't seem to get it right and keep getting the same error.
So how do I go about defining handle with the data from the json file passed into it? More specifically the handle data.
I apologize in advance if this isn't clear. Please let me know if you need further clarrification.
You can store the json in a different file assign the data to an object and you can import it like this.
import posts from 'posts.js';
Now you have access to the posts object in your component, so you can just access it using
const handle = posts[i].handle; //pass the index of array(i);
As pointed in the comment by Sean, your local state is a bit wrong. You should declare it like this:
constructor(props) {
super(props);
this.state = {handle: ''};
}
And use it like this:
axios.get('http://localhost:5000/celebs/' + this.state.handle)
Or, using Template Literals:
axios.get(`http://localhost:5000/celebs/${this.state.handle}`)
More info in the docs: https://reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class

How to display data from JSON source stored in React state - TypeError: Cannot read property 'map' of undefined

I want to get a price of Bitcoin from this JSON array.
I tried several approaches with map() function, although without success. Why does the error say it's TypeError: Cannot read property 'map' of undefined? I saw a similar question but the answers there do not work for me.
import logo from './logo.svg';
import React from 'react'
import './App.css';
import BoxComponent from './BoxComponent.js';
import Footer from './Footer.js'
import Header from './Header.js'
class App extends React.Component {
constructor(){
super()
this.state = {
loading: false,
data: []
}
}
componentDidMount() {
this.setState({loading: true})
fetch("https://api.coindesk.com/v1/bpi/currentprice.json")
.then(response => response.json())
.then(data => {
this.setState({
data: data,
loading: false
})
})
}
render(){
const price = this.state.loading ? "Loading.. :)" : this.data.map(price => <div>{price.bpi.gbp}</div>)
return (
<div className="App">
<Header />
{price}
<Footer />
</div>
);
}
}
export default App;
This is a JSON file:
{"time":{"updated":"Feb 4, 2021 20:38:00 UTC","updatedISO":"2021-02-04T20:38:00+00:00","updateduk":"Feb 4, 2021 at 20:38 GMT"},"disclaimer":"This data was produced from the CoinDesk Bitcoin Price Index (USD). Non-USD currency data converted using hourly conversion rate from openexchangerates.org","chartName":"Bitcoin","bpi":{"USD":{"code":"USD","symbol":"$","rate":"37,498.3099","description":"United States Dollar","rate_float":37498.3099},"GBP":{"code":"GBP","symbol":"£","rate":"27,422.0266","description":"British Pound Sterling","rate_float":27422.0266},"EUR":{"code":"EUR","symbol":"€","rate":"31,337.0376","description":"Euro","rate_float":31337.0376}}}
You're applying .map on something that's not an array. I would recommend reading a bit more on what map is for. MDN is a good starting point.
The first problem is that on the first render, loading will be false and your data will be undefined, so it will fail to display it. You could do this instead in your constructor:
this.state = {
loading: true,
data: undefined
}
Your render function has several issues:
First, to access state you should use this.state.data instead of this.data.
Then looking at the JSON file you've linked, the structure of your data looks like this:
{
bpi: {USD: {…}, GBP: {…}, EUR: {…}},
chartName: "Bitcoin",
disclaimer: "This data was produced from the CoinDesk Bitcoin Price Index (USD). Non-USD currency data converted using hourly conversion rate from openexchangerates.org",
time: {updated: "Feb 4, 2021 21:17:00 UTC", updatedISO: "2021-02-04T21:17:00+00:00", updateduk: "Feb 4, 2021 at 21:17 GMT"}
}
The path you're using for accessing the data doesn't match with this structure. I'll assume that you're looking for bpi.GBP.rate (but it could also be bpi.GBP.rate_float), in which case your render function should be:
render(){
const price = this.state.loading ? "Loading.. :)" : (<div>{this.state.data.bpi.GBP.rate_float}</div>)
return (
<div className="App">
<Header />
{price}
<Footer />
</div>
);
}
Also, I wouldn't keep a string for "Loading" in the price variable, but that's a different topic.
Here you have a working CodeSandbox: https://codesandbox.io/s/zealous-breeze-qwvbb (I have omitted Header and Footer for obvious reasons).

Show in Html a JSON file in Angular

I'm trying to print a JSON (link to the JSON) in an html file.
JSON:
{
"ricette": {
"FRIGGITRICI": {
"Alici": [
[
{"500": "scongelamento"}
],
[
{"60": "nada"}
]
],
"Baccalà": [
[
{"500": "scongelamento"}
],
[
{"210": "immerso"},
{"210": "cestello su"},
{"30": "immerso"}
]
]
},
"GRIGLIA": {
"Baccalà": [
[
{"500": "scongelamento"}
],
[
{"210": "immerso"},
{"210": "cestello su"},
{"30": "immerso"}
]
]
}
}
}
I've fetched it and saved in a variable:
export class DatiService {
fileJson: JSON;
constructor() { }
private datiUrl = 'https://api.myjson.com/bins/zbfh5';
async getDati(){
await fetch(this.datiUrl)
.then(res => res.json())
.then((out) => {
this.fileJson=out;
});
console.log(this.fileJson);
};
}
How can i print it in the html code?
Can i just use de "." to enter in its fields?
Or it's more complicated?
You can use the JsonPipe in your template.
{{fileJson | json}}
If you want to print a specific part you can navigate via . deeper into the object structure.
{{fileJson.ricette.FRIGGITRICI | json}}
If you want to print a primitiv value interpolation is enough and no json pipe is needed.
{{fileJson.version}}
UPDATE
Did you called your getDati function? Add an ngOnInit Lifecycle Hook and call it there. Here is an working stackblitz sample.
I just realized it's a service in your sample code. Take the service and inject it into a component and call it there.
We can use pre tag to view JSON data in HTML
Pass your JSON in var data.
And Set pre tag in HTML body.
var data = {Your JSON Object}
$("#json").innerHTML = JSON.stringify(data, undefined, 2);
<pre id="json"></pre>

Angular 6 return JSON result intead of HTML template

Is it possible to return JSON result from Angular instead of the HTML template coz we want to build something similar to a API-server? Thanks.
Here is the example that return the HTML template, how can we just return JSON without using template?
What I want to return is just a simple json result instead of HTML.
{"ID" : "1", "Name" : "Apple"}
Here is the code.
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-noresultsfound',
templateUrl: './noresultsfound.component.html',
styleUrls: ['./noresultsfound.component.css']
})
export class NoresultsfoundComponent implements OnInit {
#Input() txtval: string;
constructor(private app: AppConstants) { }
noresultsfound = this.app.noresultsfound;
ngOnInit() {
}
}
Alex
I think, he meant that pure JSON should be returned to who ever requested it by endpoint request. At least i faced something like this.
For static json, i've found an answer: https://github.com/angular/angular-cli/issues/5029
bresleveloper commented on 6 Jul 2018
1. ng-build with your index.html set properly with its components. (or conditional app-components)
2. rename and copy the rendered to (for example) /src/search.html
3. in angular.json (angular-cli.json for pre v5) find "assets":
"assets": [
"src/favicon.ico",
"src/search.html",
"src/assets"
],
browse localhost:4200/search.html
enjoy :)
Interesting part comes when u try to generate that json somehow, with browser not being involved - like some automatic service sends a request to some angular endpoint, like: hosname/statistics and in response, it receives a json which depends on number of pictures and headers on this current hosname, like {siteName: 'test', pictures: 10, headers: 1}.

EmberJS 2.7 How to restructure/reformat/customize data returned from the store

I have what I think is a very simple issue, but I just don't get how to do this data manipulation. This sadly didn't help, even though it's the same pain I am feeling with Ember.
Here is a route:
route/dashboard.js:
import Ember from 'ember';
export default Ember.Route.extend({
// this is for testing, normally we get the data from the store
model: function() {
return this.get('modelTestData');
},
modelTestData: [{
name: 'gear',
colorByPoint: true,
data: [
{y: 10, name: 'Test1'},
{y: 12, name: 'Test2'},
{y: 40, name: 'Test3'}
]
}],
});
The structure of the 'modelTestData' object has to be exactly like that as it is passed into a child component that needs it structured that way.
I can easily get my data from the API and put it into the model:
model: function() {
return this.store.get('category');
},
But then I need to restructure it...but how?
I have to somehow iterate over the categories collection and extract parts of data from each record to replace the 'data' part of the modelTestData object.
So I have 3 issues I am completely stumped on:
How to 'get at' the attributes I need from the model?
How to structure them as an array of objects with 'y' and 'name'?
How to assign that structure to the 'data' property of modelTestData instead of it being hardcoded?
Categories is a JSONAPI object like this:
{
"data":[
{
"id":"1",
"type":"categories",
"attributes":{
"name":"Carrying system",
"total-grams":"0.0"
}
},
{
"id":"2",
"type":"categories",
"attributes":{
"name":"Shelter system",
"total-grams":"0.0"
}
}
]
}
I need to map the grams value to 'y' and the name to 'name' in modelTestData.
Note that the category data is used in other routes for other purposes exactly as returned by the API. So I don't want to change the model structure itself, or what the API returns...that will break other parts of the app that do use 'category' in its original structure.
This is a specific use case that this route needs to massage the data to pass to the child component as per the structure of modelTestData.
I also wonder whether this data manipulation task belongs in a route?
Should I somehow do this in the serliazer adapter, creating a new structure as say 'categoryWeights' so I can then do:
model: function() {
return this.store.get('categoryWeights');
},
EDIT
I have managed to do this in the route, but it just gives me an array of objects. I need a single object containing 2 properties and an embedded array of objects.
model() {
return this.store.findAll('category')
.then(categories => categories.map(category => {
let data = {
y: category.get('totalGrams'),
name: category.get('name')
};
return data;
}))
},
This should probably go into a computed property:
dataForSubModel: Ember.computed('model.#each.totalGrams', 'model.#each.name', {
get() {
return [{name: 'gear', colorByPoint: true, this.get('model').map(m => ({y:m.get('totalGrams'), name:m.get('name')}))}
}
}),
The serializer is the wrong place, because its not that you need to convert it between the server and your app, but between your app and a strange component.
Actually the best thing would be to refactor the component.
Ok I got this to work in the route.
model() {
return this.store.findAll('category')
.then( function(categories) {
let data = [];
data = categories.map(category => {
return {
y: category.get('totalGrams'),
name: category.get('name')
}
});
return [{name: 'gear', colorByPoint: true, data}];
})
},
I still have the feeling this should be done in the adapter or serializer. Would be happy to see answers that show how to do that.