{this.state.object} Objects are not valid as a React child - json

I have a response json like this:
{
"variables": {
"lock": 0,
"pos": 55,
"pos_on": 55,
"pos_off": 150
},
"id": "11",
"name": "Lock_table_2",
"hardware": "esp8266",
"connected": true
}
and I try to show the lock value in 'variables' object
so I write
constructor(props) {
super(props)
this.state = {
dock_1: {}, // define a empty json
dock_2: {},
dock_3: {},
}
}
pingIP() {
axios
.get('http://192.168.50.225:8888/test_check')
.then(response => {
let data = response.data.list; // return value is a list
this.setState({ // every 2 sec setState
dock_1: data[0], // data[0] -> 192.168.50.40's json
dock_2: data[1],
dock_3: data[2],
})
})
}
render(){
return (
<p>{this.state.dock_1.variables.lock}</p>
);
}
but I got this error
in here
So I tried this
render(){
return (
<p>{this.state.dock_1.variables}</p>
);
}
then here comes the another error message
in here
here is the get request return value
{
"list": [
{
"connected": true,
"hardware": "esp8266",
"id": "10",
"name": "Lock_table_1",
"variables": {
"lock": 1,
"pos": 80,
"pos_off": 160,
"pos_on": 80
}
},
{
"connected": true,
"hardware": "esp8266",
"id": "10",
"name": "Lock_table_2",
"variables": {
"lock": 1,
"pos": 80,
"pos_off": 160,
"pos_on": 80
}
},
{
"connected": true,
"hardware": "esp8266",
"id": "10",
"name": "Lock_table_3",
"variables": {
"lock": 1,
"pos": 80,
"pos_off": 160,
"pos_on": 80
}
}
]
}
the return value is a list
in order to get first value so I wrote data[0], data1 ...
what's happening in here?

I think your response is an array of 3 items like this:
[
{
variables: {
lock: 0,
pos: 55,
pos_on: 55,
pos_off: 150
},
id: "11",
name: "Lock_table_2",
hardware: "esp8266",
connected: true
},
{
variables: {
lock: 1,
pos: 44,
pos_on: 56,
pos_off: 151
},
id: "11",
name: "Lock_table_3",
hardware: "esp8267",
connected: false
},
{
variables: {
lock: 2,
pos: 45,
pos_on: 57,
pos_off: 152
},
id: "11",
name: "Lock_table_4",
hardware: "esp8268",
connected: true
}
]
So you can access the dock 1 variable lock using Inline If with Logical && Operator to prevent null exception.
<p>{this.state.dock_1.variables && this.state.dock_1.variables.lock}</p>
A sample working codesandbox with a fake api:
https://codesandbox.io/s/stoic-chaplygin-r1yxd

Related

Read Nested JSON object in typescript in NestJs

I am new to type script and Nested JSON Object structure. I am using NestJs . Here is my JSON request
{
"recipes": [
{
"recipe_id": 1,
"ingredients": [
{
"ingredient_id": 2,
"quantity": 4,
"unit": "g",
"nutrients": [
{
"nutrient_id": 1,
"quantity": 2,
"unit": "g"
}
]
},
{
"ingredient_id": 3,
"quantity": 4,
"unit": "g",
"nutrients": [
{
"nutrient_id": 2,
"quantity": 2,
"unit": "g"
}
]
}
]
},
{
"recipe_id": 2,
"ingredients": [
{
"ingredient_id": 4,
"quantity": 4,
"unit": "g",
"nutrients": [
{
"nutrient_id": 4,
"quantity": 2,
"unit": "g"
}
]
},
{
"ingredient_id": 5,
"quantity": 4,
"unit": "g",
"nutrients": [
{
"nutrient_id": 5,
"quantity": 2,
"unit": "g"
}
]
}
]
}
]
}
Below is my code to read above json request
public async createMealRecipe(request) {
try{
const ingredientData = request.recipes.flatMap(item => {
return item.ingredients.map(({ingredient_id, quantity, unit}) =>{
return {
recipe_id: item.recipe_id, ingredient_id, quantity, unit
}
})
});
const nutrientData = request.recipes.flatMap(item1 => {
return item1.nutrients.map(({nutrient_id, quantity, unit}) =>{
return {
recipe_id: item1.recipe_id, nutrient_id, quantity, unit
}
})
});
console.log(ingredientData);
console.log(nutrientData);
}catch(e) {
console.log('e', e);
throw e;
}
}
console.log(ingredientData); is working fine, but when i try to log this console.log(nutrientData); i am getting map undefined error . Please correct me. Actually I am new to nestjs / typescript.
EDIT: `So instead of map function is there any possibility to traverse using forEach loop ?`
The issue is that request.recipes.flatMap(item1 => { doesn't give you an object representing a nutrient. item1 in this case is a recipe such as
{
recipe_id: 1,
ingredients: [
{ ingredient_id: 2, quantity: 4, unit: 'g', nutrients: [Array] },
{ ingredient_id: 3, quantity: 4, unit: 'g', nutrients: [Array] }
]
}
which also makes sense because the loop is no different than the one in which you loop over recipes above. If you'd like to loop over the nutrients of each recipe, you need to loop over the item1.ingredients array first. An example of this would be something like the following:
const nutrientData = request.recipes.flatMap(recipe => {
return recipe.ingredients.map(({ ingredient_id, quantity, unit, nutrients }) => {
return nutrients.map(({ nutrient_id, quantity, unit }) => {
return {
recipe_id: recipe.recipe_id, nutrient_id, quantity, unit
};
});
});
});

setstate() with list.lengh parameter didn't work

I tried to count the number of items in my list "data"
my component looks like that :
BuildMap() {
axios.post('http://104.xx.xx.xxx:8081/children', {action: "list"}, {headers: {'x-access-token': this.props.base.Token}})
.then(res => {
const data = res.data;
this.setState({data, NbrProfil: data.length});
})
.catch(err => console.log(err));
}
"data" is correctly returned and here is what it's return :
[
{
"name": "Mia",
"age": 12,
"options": [],
"discordId": "12",
"alerts": 0,
"warnings": 0
},
{
"name": "Demetra",
"age": 12,
"options": [],
"discordId": "12",
"alerts": 0,
"warnings": 0
}
]
sadly "NbrProfil" stay undefined and could be "2" ...
can I have some help please ?

How to groupBy data properly when using HTTP response?

here is what iam trying to achieve, i want to groupBy product_category in Array JSON but my array JSON is nested, which looks like this :
[
{
"result": "success",
"data": [
{
"product_id": 17,
"product_name": "KLO-101",
"parent_category": "Juicer"
},
{
"product_id": 42,
"product_name": "CRO-528",
"parent_category": "Vacuum Cleaner"
},
{
"product_id": 15,
"product_name": "KLC-127",
"parent_category": "Juicer"
},
{
"product_id": 41,
"product_name": "CRO-3120-WD",
"parent_category": "Vacuum Cleaner"
}
]
}
]
what the json i want to build is, below is JSON illustration that i made write manually :
[{
'Vacuum Cleaner' :
[{
"product_id": 41,
"product_name": "CRO-3120-WD",
"parent_category": "Vacuum Cleaner"
},
{
"product_id": 42,
"product_name": "CRO-528",
"parent_category": "Vacuum Cleaner"
}],
'Juicer' :
[{
"product_id": 17,
"product_name": "KLO-101",
"parent_category": "Juicer"
},
{
"product_id": 15,
"product_name": "KLC-127",
"parent_category": "Juicer"
}]
}]
from what i read, in stackoverflow somewhere its written that JSON data can be grouped with using map().groupBy() which is in my code and it looks like this :
app.service.ts :
getProductService(): Observable<any> {
return this.http
.post(global.server + "/product", this.options)
.map(a=> a.json().data)
.groupBy(
a=>a.parent_category,
a=>a
)
.catch(this.handleError);
}
and here is my app.component.ts :
getProduct() {
this.appService.getProductService().subscribe(
result => {
console.log(result);
this.dataProduct = result[0].data;
},
error => this.errorMessage = <any>error
);
}
but i get an error, 'a is undefined' how to use .groupBy() properly? angular version that i use is angular 4
UPDATE!!!
here is my code after i updated with martin answer, but still i can't figure it out, since i have to pull the JSON data from REST API, the code won't detect the 'parent_category', below is my code
app.component.ts
dataProduct : any;
getProduct() {
this.appService.getProductService().subscribe(
result => {
this.dataProduct = result[0].data;
},
error => this.errorMessage = <any>error
);
Observable.of(this.dataProduct)
.mergeMap(array => array) // unpack into single emissionns (or mergeAll() but it's broken in RxJS 5.4)
.groupBy(item => item.parent_category)
.mergeMap(observable => observable
.toArray()
.map(results => (this.dataProduct = { [results[0].parent_category]: results }))
)
.toArray()
.subscribe(console.log);
console.log(JSON.stringify(this.dataProduct));
}
i got error
[ts] Property 'parent_category' does not exist on type '{}'
In angular 1 this is the way i do
var inputdata = [
{
"result": "success",
"data": [
{
"product_id": 17,
"product_name": "KLO-101",
"parent_category": "Juicer"
},
{
"product_id": 42,
"product_name": "CRO-528",
"parent_category": "Vacuum Cleaner"
},
{
"product_id": 15,
"product_name": "KLC-127",
"parent_category": "Juicer"
},
{
"product_id": 41,
"product_name": "CRO-3120-WD",
"parent_category": "Vacuum Cleaner"
}
]
}];
var grouped = _(inputdata[0].data).groupBy(function (d) {
return d.parent_category;
});
var finalArray = _.mapObject(grouped, function (value, key) {
return value;
});
groupBy is an RxJS operator that emits Observables. In other words it returns an Observable emitting other Observables (so called "higher-order Observable"). It would be easier for you to use just map() and transform data there but if you want to go with groupBy you'll need to do some adjustments to make sure the inner Observable completes before you pass it to the resulting object:
const data = [
{
"product_id": 17,
"product_name": "KLO-101",
"parent_category": "Juicer"
},
{
"product_id": 42,
"product_name": "CRO-528",
"parent_category": "Vacuum Cleaner"
},
{
"product_id": 15,
"product_name": "KLC-127",
"parent_category": "Juicer"
},
{
"product_id": 41,
"product_name": "CRO-3120-WD",
"parent_category": "Vacuum Cleaner"
}
];
Observable.of(data)
.mergeMap(array => array) // unpack into single emissionns (or mergeAll() but it's broken in RxJS 5.4)
.groupBy(item => item.parent_category)
.mergeMap(observable => observable
.toArray()
.map(results => ({ [results[0].parent_category] : results }))
)
.toArray()
.subscribe(console.log);
Prints:
[ { Juicer: [ { product_id: 17,
product_name: 'KLO-101',
parent_category: 'Juicer' },
{ product_id: 15,
product_name: 'KLC-127',
parent_category: 'Juicer' } ] },
{ 'Vacuum Cleaner': [ { product_id: 42,
product_name: 'CRO-528',
parent_category: 'Vacuum Cleaner' },
{ product_id: 41,
product_name: 'CRO-3120-WD',
parent_category: 'Vacuum Cleaner' } ]
} ]
i think i have to implement lodash since i really confuse about observeable way, i really can't understand it, so i decided to use lodash way, it's so simple, so here is my code how to group the JSON data properly. i have to import lodash which is already include in my project, if you dont have lodash in your node_modules, you have to npm install it
import * as _ from 'lodash';
getProduct() {
this.appService.getProductService().subscribe(
result => {
this.dataTest = result;
let datas = this.dataTest;
this.dataProduct = _(datas)
.groupBy(data => data.parent_category)
.map((datas, category) => ({ category, datas }))
.value();
},
error => this.errorMessage = <any>error
);
and i just need to loop the JSON data inside "datas" with *ngFor in HTML

How can I format following json data in c3js?

How can i format following json in c3js?.
I want projectcount as y axis,date as x axis and each line for different user.
Please help me to find out this.
{"ProjectList":[{"date":"18-07-2017","projectcount":2,"user":"Salva"},
{"date":"10-07-2017","projectcount":1,"user":"Jaspreet Kaur"},
{"date":"07-07-2017","projectcount":1,"user":"Sukanya Ray"},
{"date":"29-06-2017","projectcount":1,"user":"Asmita Bhurke"},
{"date":"06-08-2017","projectcount":2,"user":"Salman AP Homes"},
{"date":"31-07-2017","projectcount":1,"user":"Alena Sandra"},
{"date":"27-07-2017","projectcount":1,"user":"Salva"},
{"date":"25-07-2017","projectcount":2,"user":"Salva"},
{"date":"21-07-2017","projectcount":1,"user":"Jaspreet Kaur"},
{"date":"21-07-2017","projectcount":2,"user":"Sandeep Ghanekar"}]}
I'll take these three data points to illustrate:
{"date":"31-07-2017","projectcount":1,"user":"Alena Sandra"},
{"date":"27-07-2017","projectcount":1,"user":"Salva"},
{"date":"25-07-2017","projectcount":2,"user":"Salva"},
For every line you want, you make an array starting with line name.
Then you set its data, filling gaps with nulls.
And you have to set timeseries array (starting with "x") from first to last date:
var chart = c3.generate({
data: {
x: 'x',
xFormat: '%d-%m-%Y', // parse format
"columns": [
[
"x",
"25-07-2017",
"26-07-2017",
"27-07-2017",
"28-07-2017",
"29-07-2017",
"30-07-2017",
"31-07-2017"
],
[
"Salva",
2,
null,
1,
null,
null,
null,
null
],
[
"Alena Sandra",
null,
null,
null,
null,
null,
null,
1
]
]
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%d-%m-%Y' // display format
}
}
},
line: {
connectNull: true
}
});
See in action.
We can format the JSON as per the graph needs.You can creates the graph as follows
var items = {
"ProjectList": [{ "date": "07-18-2017", "projectcount": 2, "user": "Salva" },
{ "date": "07-10-2017", "projectcount": 1, "user": "Jaspreet Kaur" },
{ "date": "07-07-2017", "projectcount": 1, "user": "Sukanya Ray" },
{ "date": "06-29-2017", "projectcount": 5, "user": "Asmita Bhurke" },
{ "date": "08-06-2017", "projectcount": 1, "user": "Salman AP Homes" },
{ "date": "07-31-2017", "projectcount": 3, "user": "Alena Sandra" },
{ "date": "07-27-2017", "projectcount": 4, "user": "Sandeep Ghanekar" },
{ "date": "07-25-2017", "projectcount": 2, "user": "Salva" },
{ "date": "07-21-2017", "projectcount": 6, "user": "Jaspreet Kaur" },
{ "date": "07-04-2017", "projectcount": 5, "user": "Sandeep Ghanekar" },
{ "date": "07-08-2017", "projectcount": 7, "user": "Salva" },
{ "date": "07-21-2017", "projectcount": 2, "user": "Jaspreet Kaur" },
{ "date": "07-21-2017", "projectcount": 2, "user": "Sandeep Ghanekar" }]
}
var persons=[];
var valueToPush = new Array();
var uniqueArray = items.ProjectList.reduce(function (a, d) {
if (a.indexOf(d.date) === -1) {
a.push(""+d.date+"");
}
return a;
}, ['x']);
uniqueArray.sort(function(a, b) {
dateA = new Date(a),
dateB = new Date(b);
return dateA - dateB;
});
var nameArray = items.ProjectList.reduce(function (a, d) {
if (a.indexOf(d.user) === -1) {
a.push(""+d.user+"");
}
return a;
}, []);
valueToPush[0]=uniqueArray;
var i=1;
nameArray.forEach(function(c){
persons=[];
persons.push(""+c+"")
items.ProjectList.forEach(function(b){
if(c===b.user){
persons.push(b.projectcount)
}
else{
persons.push(null)
}
});
valueToPush[i]=persons;
i++;
});
var chart = c3.generate({
data: {
x: 'x',
xFormat: '%d-%m-%Y',
"columns": valueToPush
},
axis: {
x: {
type: 'category',
tick: {
format: '%d-%m-%Y'
}
}
},
line: {
connectNull: true
}
});
Mention JavaScript support Date formats
Try this JSFiddle

Elasticsearch: how to store all json objects dynamically

I'm trying to store all Json objects through elasticsearch.
client.create({
index: 'index',
type: 'type',
id:"1"
body:result[0]
},function (error,response)
{
if (error)
{
console.log('elasticsearch cluster is down!');
}
else
{
console.log('All is well');
}
});
In this result[0] I'm getting my first value of a Json object but I need to store all Json objects dynamically.
The output which i'm getting is:
-> POST http://localhost:9200/index/type/1?op_type=create
{
"Name": "Martin",
"Age": "43",
"Address": "trichy"
}
<- 201
{
"_index": "index",
"_type": "type",
"_id": "1",
"_version": 4,
"created": true
}
But I need an output like this:
-> POST http://localhost:9200/index/type/1?op_type=create
{
"Name": "Martin",
"Age": "43",
"Address": "trichy"
},
{
"Name": "vel",
"Age": "23",
"Address": "chennai"
},
{
"Name": "ajay",
"Age": "23",
"Address": "chennai"
}
<- 201
{
"_index": "index",
"_type": "type",
"_id": "1",
"_version": 4,
"created": true
}
What you need is to use the bulk endpoint in order to send many documents at the same time.
The body contains two rows per document, the first row contains the index, type and id of the document and the document itself is in the next row. Rinse and repeat for each document.
client.bulk({
body: [
// action description
{ index: { _index: 'index', _type: 'type', _id: 1 } },
// the document to index
{ Name: 'Martin', Age: 43, Address: 'trichy' },
{ index: { _index: 'index', _type: 'type', _id: 2 } },
{ Name: 'vel', Age: 23, Address: 'chennai' },
{ index: { _index: 'index', _type: 'type', _id: 3 } },
{ Name: 'ajay', Age: 23, Address: 'chennai' }
]
}, function (err, resp) {
// ...
});
I suspect your result array is the JSON you get from your other question from yesterday. If so, then you can build the bulk body dynamically, like this:
var body = [];
result.forEach(function(row, id) {
body.push({ index: { _index: 'index', _type: 'type', _id: (id+1) } });
body.push(row);
});
Then you can use the body in your bulk call like this:
client.bulk({
body: body
}, function (err, resp) {
// ...
});