React : object is undefined when using loops and useState [duplicate] - javascript

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Why is setState in reactjs Async instead of Sync?
(8 answers)
Closed 1 year ago.
I have this code
import React from 'react';
import { Button, Image, StyleSheet, Text, View } from 'react-native';
function App() {
const firstCategory = [
{ id: 1, name: 'person1' },
{ id: 2, name: 'person2' },
{ id: 3, name: 'person3' },
{ id: 4, name: 'person4' },
];
const [secondCategory, setSecondCategory] = React.useState([
{ id: 5, name: 'person5' },
{ id: 6, name: 'person6' },
{ id: 7, name: 'person7' },
{ id: 8, name: 'person8' },
]);
React.useEffect(() => {
setSecondCategory([]);
for (var i = 0; i < firstCategory.length; i++) {
setSecondCategory((secondCategoryArray) => [...secondCategoryArray, firstCategory[i]]);
}
},[]);
return (
<View>
{secondCategory.map((item) => {
return <Text>{item.name}</Text>;
})}
</View>
);
}
export default App;
It is supposed to empty the secondCategory array and fill it with firstCategory array but when I console.log secondCategory array I get [undefined,undefined,undefined,undefined] and I get the error message 'cannot read property name of undefined'.
I know that there are many other ways to achieve the wanted result but I want to know exactly the cause of this problem in this specific situation.

Related

Nested array of object data display on UI [duplicate]

This question already has answers here:
How to use nested Map in React component with the given data
(2 answers)
Closed 3 months ago.
I have following response from backend as an array of object,
const cloudData = [
{
dataCenter: "AWS-East",
availablechannels: [
{
channelName: "E-channel1",
id: 1,
},
{
channelName: "E-channel2",
id: 2,
},
{
channelName: "E-channel3",
id: 3,
},
],
},
{
dataCenter: "AWS-West",
availablechannels: [
{
channelName: "W-channel1",
id: 1,
},
{
channelName: "W-channel2",
id: 2,
},
{
channelName: "W-channel3",
id: 3,
},
],
},
];
I need to display on UI grid in following way ,
AWS East
E-channel1
E-channel2
E-channel3
I have tried using es6 map and filter
You can do this :
cloudData.forEach((datacenter)=> {
console.log(datacenter.dataCenter)
datacenter.availablechannels.forEach((channel)=>{
console.log(channel.channelName)
})
})

How to limit an array field in javascript object to a certain length

I know this may a simple problem but I have a the following javascript object:
const categories = {
title: 'cat1',
contents: [
{
name: 'cont1'
},
{
name: 'cont2'
},
{
name: 'cont3'
}
]
}
How can a transform this categories object so it has only 2 contents element as an example?
const transformedCategories = {
title: 'cat1',
contents: [
{
name: 'cont1'
},
{
name: 'cont2'
}
]
}
A couple of ways to do it:
const transformedCategories = {
title: categories.title,
contents: categories.contents.slice(0,2) // you can also use splice here
}
Another, slightly cheeky way:
const contents = [...categories.contents];
contents.length = 2;
const transformedCategories = {...categories, contents}

I want to generate an object of objects, who also contain objects, based on WP categories/subcategories [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I've been working with WP REST Api to migrate an app to a headless wp + react app and got some problems with how WP displays Cats and SubCats.
My idea is to get all the current categories and generate children of based on the father category, those children also can get childrens, since WP cat-subcat structure is infinite.
Category { SubCategory { SubCategory {infinite}}}
I've been trying to generate a new Object that contains this info and iterate in different ways, like pushing the one who has 'parentId' equals to father ID, but constantly getting undefined.
My current logic is something like this:
const fatherCategories = categories.filter((item) => (
item.parent === 0
))
const subCategories = categories.filter((item) => (
item.parent !== 0
))
const subCategories = subCats.forEach((category) => (
subCats.filter((item) => (
category.id === item.parent
))
))
Im 100% that this is not the way i need to get my objective but my knowledge stops here and can't get any solution for this problem, if i know the lenght of the subcategories i will go another way, but without this data, im blocked.
As my previous comment says something like this should work for you:
function isParent(category) {
return category.parent === 0;
}
function findAllchildren(allCategories, currentCategory) {
// const allCategories.filter()
const currCatChildren = allCategories.filter(
(c) => c.parent === currentCategory.id
);
if (currCatChildren.length) {
currCatChildren.forEach((c) => {
c.children = findAllchildren(allCategories, c);
});
}
return currCatChildren;
}
const categories = [
{ id: 1, parent: 0, name: "pc -> 1" },
{ id: 2, parent: 0, name: "pc -> 2" },
{ id: 3, parent: 1, name: "cc -> 3>1" },
{ id: 4, parent: 2, name: "cc -> 4>2" },
{ id: 5, parent: 3, name: "cc -> 5>3" },
{ id: 6, parent: 4, name: "cc -> 6>4>1" },
{ id: 7, parent: 5, name: "cc -> 7>5>3>1" },
];
const finalCategoryTree = categories.filter(isParent).map((parentCategory) => {
const tmp = { ...parentCategory };
tmp.children = findAllchildren(categories, parentCategory);
return tmp;
});
console.log(JSON.stringify(finalCategoryTree));

Filter an array of objects with a second array with multiple values

I am trying to write a function to take the first object in the "parent" array, pull out the child field (which is in that array) and use that field to filter the second object called "child".
I want to get all the related records from the child object that are in the child field in the parent object.
Expected output
child: [
{
**id: 1,**
name: 'Jimmy Yukka',
},
{
**id: 2,**
name: 'Up North',
}
INPUT
Parent: [
{
**id: 1,**
name: 'Melbourne Bands',
**child: [1, 2]**
}
I have the following data
Parent: [
{
**id: 1,**
name: 'Melbourne Bands',
**child: [1, 2]**
},
{
id: 2,
name: 'Sydney Bands',
child: [3]
}
],
child: [
{
**id: 1,**
name: 'Jimmy Yukka',
},
{
**id: 2,**
name: 'Up North',
},
{
id: 3,
url: 'jimmyyukka.com',
name: 'INXS',
CreatedByUserId: 1
}
],
The code of the function I have implemented so far:
currentChildrenIds(ParentId, parentData, childData) {
const singleParentRecord = parentData.filter(function(parent) {
return parent.id === ParentId;
});
const parentsChildIds = singleParentRecord[0].books;
const childRecords = childData.filter(function(child) {
return child.id === parentsChildIds
});
return childRecords
}
NOTES
This bit here is where it is wrong
const childRecords = childData.filter(function(child) {
return child.id === parentsChildIds
This bit here is also a bit rubbish (hardcoding the [0])but not I'm not sure how I should be coding it correctly
const parentsChildIds = singleParentRecord[0].books;
here,
const childRecords = childData.filter(function(child) {
return child.id === parentsChildIds
parentsChildIds is a reference to an array: you don't want to test if an id is === to a a reference,
You have to be explicit and check if the id is contained in the array:
const childRecords = childData.filter(function(child) {
return parentsChildIds.includes(child.id)
Regarding the singleParentRecord[0] that does feel weird,
since you know the method filter will always return an array of size 1 or 0,
you can use the method find instead of filter
Also in functionnal programming (array functions such as filter, map, find...)
I advice you to read a bit about the arrow function syntax because:
The syntex is more dense and it makes it easier for your brain to understand when several functions are chained
If you want to use variables which are defined outside of the function it will be available only inside of an arrow function
your code with an arrow function:
const childRecords = childData.filter((child) => {
return child.id === parentsChildIds
}
Try this:
const Parent = [
{
id: 1,
name: 'Melbourne Bands',
child: [1, 2]
},
{
id: 2,
name: 'Sydney Bands',
child: [3]
}
];
const children = [
{
id: 1,
name: 'Jimmy Yukka',
},
{
id: 2,
name: 'Up North',
},
{
id: 3,
url: 'jimmyyukka.com',
name: 'INXS',
CreatedByUserId: 1
}
];
// We create a new array with Array.map
const result = Parent.map(parent => ({
// Spread properties of the parent
...parent,
// Override the child property and filter the children array with the `includes` method
child: children.filter(child => parent.child.includes(child.id)),
}))
console.log(result);

Simply return a value from another component

Wondering if you guys can help. I am trying to create a generic component which when called, will return a value.
The code currently stands as follows:
import React, {Component} from 'react'
class Clients extends Component {
render () {
var userEnum = {
SMALL: 1,
MEDIUM: 2,
LARGE: 3,
properties: {
1: {name: "Admin", value: 1},
2: {name: "Manager", value: 2},
3: {name: "Standard", value: 3}
}
};
const clientName = (value) => {
return userEnum.properties[value].name
}
return null
}
}
export default Clients
and in another component, I try calling the clientName function (done an import too).
import ClientHelper from '../../helpers/clients'
...
const test = ClientHelper.clientName(2)
console.log(test)
I should expect a return value of 'Manager' but I get
TypeError: WEBPACK_IMPORTED_MODULE_9__helpers_clients.a.clientName
is not a function
You are declaring the function clientName inside the render method of the class Clients. This function is only accessible inside it's scope, the render method.
To access the function like you would, by calling the class Clients static method clientName, you should write it like this:
import React, { Component } from 'react'
class Clients extends Component {
static userEnum = {
SMALL: 1,
MEDIUM: 2,
LARGE: 3,
properties: {
1: { name: "Admin", value: 1 },
2: { name: "Manager", value: 2 },
3: { name: "Standard", value: 3 }
}
};
static clientName(value) {
return Clients.userEnum.properties[value].name;
}
render() {
return null;
}
}
export default Clients
If you do not intend to render anything with this class, you do not need react, and can simply create a utility/static class like below:
export default class Clients {
static userEnum = {
SMALL: 1,
MEDIUM: 2,
LARGE: 3,
properties: {
1: { name: "Admin", value: 1 },
2: { name: "Manager", value: 2 },
3: { name: "Standard", value: 3 }
}
};
static clientName(value) {
return Clients.userEnum.properties[value].name;
}
}
the function clientName is not a property of your class, but a local function inside the render function and therefore not accessible from the outside.
To solve this, you have to make clientName as well as your userEnum properties of the Clients object, for example in the constructor:
import React, {Component} from 'react'
class Clients extends Component {
constructor(props){
super(props);
this.userEnum = {
SMALL: 1,
MEDIUM: 2,
LARGE: 3,
properties: {
1: {name: "Admin", value: 1},
2: {name: "Manager", value: 2},
3: {name: "Standard", value: 3}
}
};
}
function clientName (value) {
return this.userEnum.properties[value].name
}
function render () {
return null
}
}
export default Clients

Categories

Resources