How can I access the data in a nested array? - javascript

I'm looping through some data. Here's the JSX: For now I'm using console.log to figure out how to access the data.
<div>
<ul>
{orderData &&
orderData.map(item => {
return <Order item={item} />;
})}
</ul>
</div>
export default function workorder({ item }) {
console.log(
Object.values(item.data).map(item => {
return item;
})
);
return <h1></h1>;
}
Right now,
console.log(
Object.values(item.data).map(item => {
return item;
})
);
returns this, which is what I want:
I can easily access the values inside all of the arrays excepting the first one, with something like item.name or item.email
But the question is: how can I access the data inside of Array(20)? I want to render data such as deadline or description.
Attempting: item.deadline returns this:
So what should I be doing here?

I belive "item" is an array, and you will want to access the array using item[0] to get an individual item. (between 0 and 19 to access individual items in the array).
It also looks like an array inside of an array, so you will have to access it twice.
So what you will want to do is use item[0][0].deadline to get the deadline property of the first object.

Related

filtering out an array of items setting state

I am looking to filter through an array and return all elements of the array except the element which has been clicked on, so I have a map of list elements each with a key={index} of their map, onClick it should call my remove function, and pass in the index of the element to be removed, I then need to filter over that array, remove the element, update state, and send this information to my backend.
here is the delete function
const deleteItem = (id) => {
// use filter, to loop through all pieces of index
const element = list.todoItems.indexOf(id - 1);
setList({ todoItems: list.todoItems.filter(element !== id) });
console.log(list.todoItems);
dispatch(updateTodo(list));
};
here is the mapped array
{list.todoItems.map((Item, index) => (
<div
// setup anonymous function, that will call
// ONLY when the div
// is clicked on.
key={index}
onClick={() => deleteItem(index)}
>
{/* list item, gets text from props */}
<li>{Item}</li>
</div>
))}
I must be missing something, because this should work, Though i may have to shift gears and have each item as an actual object in my database, though id rather not do this as i feel an array of strings is more than appropriate for this app.
Remove your indexOf logic and this will work.
You don't have to find the index of the array because you're already receiving it as a parameter.
const deleteItem = (id) => {
setList({ todoItems: list.todoItems.filter((_, filterID) => filterID !== id) });
console.log(list.todoItems);
dispatch(updateTodo(list));
};
You don't need to subtract one from the index on the indexOf function
And for this case, splice works better than filter
const deleteItem = (id) => {
const element = list.todoItems.indexOf(id);
setList({ todoItems: {...list}.todoItems.splice(element, 1)});
dispatch(updateTodo(list));
};

How to loop through object with 2 arrays?

Trying to loop throught State passed by props on other component
state = {
question:[firstQ, secondQ, thirdQ],
tag:[[1,2,3],[4,6],[a,b,c,d]]
}
I want to render it on next Componet with Patter like:
FirstQ
[tag1]
SecondQ
[tag2]
ThirdQ
[tag3]
etc
I was trying lot of option but getting always something like
FirstQ
SecondQ
ThirdQ
[tag1]
[tag2]
[tag3]
EDIT:
Passing data to second Component with
question={this.state.question}
tag={this.state.tag}
EDIT2:
For now i made loops like this
{this.props.question.map((item,) => {
return (<span key={item}>{item}</span>)
})}
{this.props.tag.map((item) => {
return (<span>{item<span>)
})}
I trying to render this two arrays as pairs Question1 => Tag1 then underneath second Question2 = >tag2 etc.
Use the index of question to get matching tags
Something like:
{this.state.question.map((q,i)=>{
return (
<div>
<h4>{q}</h4>
Tags: {this.state.tag[i].join()}// map these to element you want instead of join()
</div>
)
})

React render array to add to a list - simple return not working

I've created a simple object
const customer = { name : "foo", phone : "519-500-5000", orders : { crust: "normal", toppings : ["Cheese", "Bacon"]} }
it holds a internal object called "orders" that has also has an array of toppings, in these case "Cheese" and "Bacon".
I've extracted the array out and passed it into a render toppings function
renderToppings (toppings) {
console.log("render Toppings: ", toppings) // Renders the whole array of toppings, good.
toppings.forEach(function (topping) {
//return (
// <li> {topping} </li>
//)
console.log("each Topping: ", topping) // This DOES render each topping separately as expected.
});
}
I created a list that has other values, then I eventually called my render method (which is within the same class)
{this.renderToppings (PizzaToppings)}
the console log does return the values I was expecting. But when I uncomment out the return, it doesn't do the console nor does it print the the toppings.
What am I missing here? Sorry if this is all sloppy, I'm new to react.
You aren't returning to anything. The return value of a forEach() callback is not used.
Use map() instead to generate an array of your elements and return that
return toppings.map(function (topping) {
return (
<li> {topping} </li>
);
});
Demo
class Pizza extends React.Component {
render() {
var toppings = ['cheese', 'sausage', 'never pineapple'];
var elements = toppings.map(topping => {
return (
<li>
{topping}
</li>
);
});
return (
<ul id = "toppings">
{elements}
</ul>
);
}
}
ReactDOM.render(
<Pizza /> ,
document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
forEach doesn't return anything(returns undefined), you need to use map function
renderToppings (toppings) {
return toppings.map((topping) => {
return (
<li> {topping} </li>
)
});
}
You are using .forEach and a forEach only calls a given method on each item of the array and does nothing with the return value.
Use .map instead, map returns a new array. It also calls a method on each item in the array but allows you to return a new value for each item it iterates.
renderToppings (toppings) {
toppings.map(function (topping) {
return (
<li> {topping} </li>
)
});
}
Would work in your case
The callback in .forEach modifies the original array, but for React to render the element you should create a new array with .map

Find First Iteration of Map in React/Javascript

I'm mapping an object array in React and I want to find the first iteration of chosenFields array.
People Array:
[ { id:1, name:"Jim", occupation:"Programmer".........}
{id:2, name:"Sally", occupation:"Pet Sitter".......}]
I have another object array that is in charge of what fields are suppose to be displayed from the PeopleArray:
chosenFields Array:
[{label:"id", show:true}, {label:"name", show:true}, {label:"occupation", show:false}]
I want to know if there's a way that the code can recognize when it first iterates through chosenFields Array for each row of the People Array
renderSingleData(rowListData, currData){
//find which one is the first iteration to add a radiobox for each row
}
renderUserData(currRow){
return(
<div>
{chosenFields.map(this.renderChosenData.bind(this, currRow)}
</div>
)
}
render() {
return (
<div >
{PeopleData.map(this.renderUserData.bind(this))}
</div>
);
}
}
This is a very simplified version of the code. I need to add an iteration to a table via <td>. I'm currently using a variable in React and setting the state with a counter. I'm wondering if there's a more straightforward way to find iterations via the map function.
Take a look at the docs for Array.prototype.map()
The callback function's second argument is the index. If this is 0, then that is the first iteration of the callback. In your case, you may need to propagate that condition up a few callbacks. Something like...
renderSingleData(isFirst, rowListData, currData){
//find which one is the first iteration to add a radiobox for each row
}
renderUserData(currRow, currIdx){
return(
<div>
{chosenFields.map(this.renderChosenData.bind(this, currIdx === 0, currRow)}
</div>
)
}
render() {
return (
<div >
{PeopleData.map(this.renderUserData.bind(this))}
</div>
);
}

Using map to iterate through two arrays

Currently in React, I am using array.map(function(text,index){}) to iterate through an array. But, how am I going to iterate through two arrays simultaneously using map?
EDIT
var sentenceList = sentences.map(function(text,index){
return <ListGroupItem key={index}>{text}</ListGroupItem>;
})
return (
<div>
<ListGroup>
{sentenceList}
</ListGrouup>
</div>
);
Like, in this I want icons to be prepended with every iteration. And I'm planning to have those icons in another array. So, thats why iterate two arrays.
If at all possible, I would recommend storing the text alongside the images in an array of objects, eg:
const objects = [{text: 'abc', image: '/img.png' }, /* others */];
that way you can just iterate through the array and select both members at the same time, for example:
objects.map(item => (<Component icon={item.image} text={item.text} />) )
If this isn't possible then just map over one array and access the second array's members via the current index:
sentences.map((text, index) => {
const image = images[index];
return (<Component icon={image} text={text} />);
});
Are the both arrays of same length? You can do something like below if your intention is to combine both in some way.
array.map(function(text,index){
return text + ' ' + array2[index]
})
In your case:
var sentenceList = sentences.map(function(text,index){
return <ListGroupItem key={index}>{text} <img src={icons[index]} /i> </ListGroupItem>;
})
return (
<div>
<ListGroup>
{sentenceList}
</ListGrouup>
</div>
);
Notice, How Icon src is being assigned. The idea is that access icons array with the same index to get a corresponding icon.
You can't do this with built-in Array.prototype methods, but you can use something like this:
function map2(arr1, arr2, func) {
return arr1.map(
(el, i) => { return func(el, arr2[i]); }
);
}
(Of course, arr1 and arr2 are expected to have the same length)
Generally, what you're looking for is a zip function, such as the one that lodash provides. Much like a real zipper, it combines two things of the same length into one:
const zipped = _.zip(sentences, icons);
return (
<div>
<ListGroup>
{zipped.map(([sentence, icon], index) => (
<ListGroupItem key={index}><Icon icon={icon} /> {text}</ListGroupItem>;
))}
</ListGroup>
</div>
);
Note, this is doing more iterations than are technically needed. If performance is an issue, you may want a solution that's a bit smart (not really in scope for your question though).

Categories

Resources