Cannot save an object in the state with its keys in react - javascript

These are the functions that I use for my class component
constructor() {
super();
this.state = {
data: []
}
}
async componentDidMount() {
var citas_data = await makeRequest('api/products/');
citas_data.data.map(data => (
this.setState({
data: [...this.state.data, [{ id: data._id, name: data.name }]]
})
))
}
This is the information contained in the var citas_data, brings it from an api I have in nodejs.
{
"data": [
{
"_id": "600db7499f933921c0a56f95",
"name": "laptop hp 8gb",
"category": "razer",
"price": 80000,
"imgUrl": "https://cnet1.cbsistatic.com/img/P2IudsL7buTCG7zvs4gq5BNpOS4=/470x376/2018/06/27/ba86ad23-6537-4466-b709-e3eaeb662700/11-asus-tuf-gaming-fx504.jpg",
"createdAt": "2021-01-24T18:07:05.811Z",
"updatedAt": "2021-01-24T18:07:22.941Z"
},
{
"_id": "600e39f22ac1a14a10c8ed59",
"name": "laptopa razer",
"category": "raazer",
"price": 99000,
"imgUrl": "https://cnet1.cbsistatic.com/img/P2IudsL7buTCG7zvs4gq5BNpOS4=/470x376/2018/06/27/ba86ad23-6537-4466-b709-e3eaeb662700/11-asus-tuf-gaming-fx504.jpg",
"createdAt": "2021-01-25T03:24:34.776Z",
"updatedAt": "2021-01-25T03:24:34.776Z"
},
{
"_id": "600e3d607e0b6b44d8e98bf8",
"name": "laptopa razer",
"category": "raazer",
"price": 99000,
"imgUrl": "https://cnet1.cbsistatic.com/img/P2IudsL7buTCG7zvs4gq5BNpOS4=/470x376/2018/06/27/ba86ad23-6537-4466-b709-e3eaeb662700/11-asus-tuf-gaming-fx504.jpg",
"createdAt": "2021-01-25T03:39:12.093Z",
"updatedAt": "2021-01-25T03:39:12.093Z"
}
],
"status": 200,
"statusText": "OK",
And when executing the code I get these errors Error: Objects are not valid as a React child (found: object with keys {id, name}). If you meant to render a collection of children, use an array instead.
11 |
12 | async componentDidMount() {
13 | var citas_data = await makeRequest('api/products/');
> 14 | citas_data.data.map(data => (
15 | this.setState({
16 | data: [...this.state.data, [{ id: data._id, name: data.name },]]
17 | })

The solution was to change the name of the state "data" to a different one.
Example:
constructor() {
super();
this.state = {
data: []
}
}
To:
constructor() {
super();
this.state = {
dates: []
}
}

**try to do that**
async componentDidMount() {
const results=[]
const citas_data = await makeRequest('api/products/');
citas_data.forEach(item => {
results.push({
id: data._id,
name: data.name
});
});
this.setState({data:results});

Related

How to map an array from json that contains two arrays?

I fetch data from json and try to display one of the arrays in my componenet but I get an error that map is not a function, what do I do wrong? How to get only one array of two? Is it array I have in json or an object?
import React, { Component } from 'react';
class Customer extends Component {
constructor() {
super();
this.state = {
customers : []
};
}
componentDidMount() {
fetch('myURL')
.then(response => response.json())
.then(json => this.setState({ customers: json}))
}
render () {
return (
<div>
{this.state.customers && this.state.customers.map(cust => (
<div>
<h1>{cust.CustomerName}</h1>
</div>
)
})}
</div>
)
}
}
export default Customer;
And my JSON file has two arrays that looks like this:
{
"fields": [
{
"id": "Customer_ID",
"description": "Customer ID",
"type": "Key",
},
{
"id": "Customer_ID",
"description": "Customer ID",
"type": "Key",
},
],
"list_items": [{"Customer_ID":1,"CustomerName":"ABS","CustomerType":"DTS"},
{"Customer_ID":2,"CustomerName":"Giu Sto","CustomerType":"STD"}]
}
You did not asign the items to customers in state. You should do it like this
componentDidMount() {
fetch('myURL')
.then(response => response.json())
.then(json => this.setState({ customers: json.list_items}))
}
I hope this solves your problem
Edit:
this.setState({customers:json}) will change customers state to an object which is not itterable and have the value of your json file customers:{fields: [...],list_items: [...]} but you only want list_items to be assigned to customers that's why you should access list_items from json and assign it directly to customers this.setState({customers:json.list_items_}
try logging whether the array is present or not.
const my_json = {
fields: [
{
id: "Customer_ID",
description: "Customer ID",
type: "Key",
},
{
id: "Customer_ID",
description: "Customer ID",
type: "Key",
},
],
list_items: [
{ Customer_ID: 1, CustomerName: "ABS", CustomerType: "DTS" },
{ Customer_ID: 2, CustomerName: "Giu Sto", CustomerType: "STD" },
],
};
my_json.list_items.map(customer => console.log(customer.CustomerName))

How to parse FractalTransformer with normalizr

I'm trying to use paularmstrong/normalizr on JSON that comes from FractalTransformer and whose nested childs have "data" attribute. Example of JSON:
{
"data": {
"object": "Offer",
"id": "5g6aqocew4qjzl40",
"real_id": 26,
"name": "Random Name",
"created_at": {
"date": "2019-06-18 11:13:08.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"readable_created_at": "1 year ago",
"site": {
"data": {
"object": "Site",
"id": "65zody8vj29vlegd",
"name": "Test Site",
"real_id": 1
}
},
"countries": {
"data": [
{
"object": "Country",
"code": "US",
"name": "United States"
},
{
"object": "Country",
"code": "DE",
"name": "Germany"
}
]
}
},
"meta": {
"include": [
"site",
"countries"
],
"custom": []
}
}
Schemas I use:
export const offerSchema = new schema.Entity('offers')
export const siteSchema = new schema.Entity('sites', {}, {
processStrategy: (value) => {
return { ...value.data }
},
idAttribute: (value) => {
return value.data.id
},
})
export const countrySchema = new schema.Entity('countries')
offerSchema.define({
site: siteSchema,
countries: [countrySchema],
})
Now the issue is that I remove 'data' from the site since it's just one object successfully, but I can't do it in the country case. Whatever I tried with custom processStrategy fails, as country is object that has data which is array (I assume this is where the issue is, going from Entity to Array). And in idAttribute function I always get complete array so can't determine the ID of single entry. So the end result is that the ID of countries is undefined. Any ides?
I actually managed with another approach. I added processStrategy on the parent, 'Offer' in this case, so all 'data' parts get stripped before they reach other child schemas.
const normalizrStripDataOptions = {
processStrategy: (value) => {
const ret = { ...value }
Object.keys(ret).forEach((key) => {
if (ret[key] !== null) {
if (ret[key].data && Array.isArray(ret[key].data)) {
ret[key] = [...ret[key].data]
}
if (ret[key].data && typeof ret[key].data === 'object') {
ret[key] = { ...ret[key].data }
}
}
})
return ret
},
}
export const offerSchema = new schema.Entity('offers', {}, normalizrStripDataOptions)
export const siteSchema = new schema.Entity('sites')
export const countrySchema = new schema.Entity('countries')
offerSchema.define({
site: siteSchema,
countries: [countrySchema],
})

Modify javascript object to specific format

let data = {
"rec": [{
"id": "25837",
"contentId": "25838"
},
{
"id": "25839",
"contentId": "25838"
},
{
"id": "25838"
},
{
"id": "25636",
"contentId": "25837"
}, {
"id": "25640",
"contentId": "25839"
}
]
};
I have a javascript object which I have to manipulate to below format.
{
"childern": [{
"id": "25838",
"childern": [{
"id": "25837",
"contentId": "25838",
"childern": [{
"id": "25636",
"contentId": "25837"
}]
},
{
"id": "25839",
"contentId": "25838",
"childern": [{
"id": "25640",
"contentId": "25839"
}]
}
]
}]
}
If any object dont have contentId it should be at parent level. then all the objects having contentId same as parent id should be at its child level and so on.
I have created a fiddle here but logic is not completed. Any idea or reference to achieve this.
You could create recursive function with reduce method to get the desired result.
let data = {"rec":[{"id":"25837","contentId":"25838"},{"id":"25839","contentId":"25838"},{"id":"25838"},{"id":"25636","contentId":"25837"},{"id":"25640","contentId":"25839"}]}
function nest(data, pid) {
return data.reduce((r, e) => {
if (pid == e.contentId) {
const obj = { ...e }
const children = nest(data, e.id);
if (children.length) obj.children = children
r.push(obj)
}
return r;
}, [])
}
const result = nest(data.rec);
console.log(result[0])

ReactJS - How to migrate from json-server to a .json file?

I have this db.json and I want to migrate to file. How do I implement it? I had tried this way above and it didn't work for me. When I put the file in src folder, there appears an error message:
Module not found: Can't resolve 'houses.json' in 'C:\Users\user\Desktop\dir\src'
It does the same thing when I put the file in the public folder.
It is my db.json file:
{ "houses": [
{
"id": 1,
"name": "Title here",
"text": "Text here",
"photos": [
"pic1",
"pic2",
"pic3"
]
},
"houses": [
{
"id": 2,
"name": "Title here",
"text": "Text here",
"photos": [
"pic1",
"pic2",
"pic3"
]
},
"houses": [
{
"id": 3,
"name": "Title here",
"text": "Text here",
"photos": [
"pic1",
"pic2",
"pic3"
]
}
}
I had traded this line
const URL = 'http://localhost:3001/houses';
for this other
const URL = require('houses.json');
And it caused the error message showed before.
And how do I fetch these datas from axios? I was fetching datas from json-server doing this way below. It was successfully. I want to do the same thing but not from json-server but using .json file.
const URL = 'http://localhost:3001/houses';
class House extends Component {
constructor(props) {
super(props);
this.state = {
index: 0,
totalHouses: [],
currentHouse: [],
name: [],
photos: [],
text: []
};
}
componentDidMount() {
axios.get(URL)
.then(res => {
this.setState({
totalHouses: Object.keys(res.data),
currentHouse: res.data
})
})
}
//...rest of the code omitted
Here's a simple example how to achieve what you need, while preserving your state approach.
const houses = require('./houses.json');
class House extends Component {
constructor(props) {
super(props);
this.state = {
index: 0,
totalHouses: [],
currentHouse: [],
name: [],
photos: [],
text: []
};
}
componentDidMount() {
this.setState({
totalHouses: Object.keys(houses.data),
currentHouse: houses.data
})
}
//...
}
You can also achieve it without componentDidMount:
const houses = require('./houses.json');
class House extends Component {
constructor(props) {
super(props);
this.state = {
index: 0,
totalHouses: Object.keys(houses.data),
currentHouse: houses.data
name: [],
photos: [],
text: []
};
}
//...
}
It should be require('./houses.json');. Right now it looks for this file inside node_modules or even higher.

Accessing data in an array List using axios.get in React Native

How to Make a Accessing data in an array, and list separated by categories Using axios React Native
I am trying to deploy a list with categories and products using axio in react native
my json structure
[
{
"id": "1",
"name": "TV",
"list": [
{
"idp": "1",
"namep": "TV 43"
},
{
"idp": "2",
"namep": "TV 32"
}
]
},
{
"id": "2",
"name": "Couch",
"list": [
{
"idp": "3",
"namep": "Couch for 3 people"
},
{
"idp": "4",
"namep": "Couch for 2 people"
}
]
}
]
what I've already done, so I can display categories
constructor(props) {
super(props);
this.state = { category: [], list: [] };
}
componentWillMount() {
axios.get('http://localhost/api/list.json')
.then(response => {
this.setState({
category: response.data,
list: response.data.list });
})
.catch(() => { console.log('Err'); });
}
.............
{this.state.category.map((item, i) => {
<Text>{item.name}</Text>
{ item.list.map((product, i) => {
<Text>{product.namep}</Text>
})}
})}
Example list
Sorry I can't give you a more detailed and focused answer since I'm not familiar with react native but logic goes like this:
A loop to iterate over main array and extract categories names then another loop inside that one for iterating over products.
const arr = [
{
"id": "1",
"name": "TV",
"list": [
{
"idp": "1",
"namep": "TV 43"
},
{
"idp": "2",
"namep": "TV 32"
}
]
},
{
"id": "2",
"name": "Couch",
"list": [
{
"idp": "3",
"namep": "Couch for 3 people"
},
{
"idp": "4",
"namep": "Couch for 2 people"
}
]
}
];
const parentEl = document.querySelector('#list');
arr.forEach((cat) => {
const catEl = document.createElement('div')
catEl.textContent = cat.name
parentEl.append(catEl)
cat.list.forEach((prod) => {
const listEl = document.createElement('ul')
const listItem = document.createElement('li')
listItem.textContent = prod.namep
listEl.append(listItem)
parentEl.append(listEl)
})
})
<div id="list">
</div>
So, not knowing react native AND assuming this code you pasted is correct, I'm going to risk saying it would go something like this:
{
this.state.category.forEach((item, i) => {
<Text>{item.name}</Text>
item.list.forEach((product, i) => {
<Text>{product.namep}</Text>
})
})
}

Categories

Resources