Adding property in array. Add the last value in all array - reactjs

"I'm adding a property on array while in a forEach loop. But when I do the console.log() the added value on each array is always the last value of the foreach loop."
deliveries data has location and I want to pass the location to pickupDetails.
deliveries: [{ //data of deliveries that I want to pass in pickupDetails
0: {Location: Korea},
1: {Location: Japan}
}]
let pickupDetails = this.state.pickupDetails;
//pickupDetails is only one object then It will become two since the deliveries has 2 objects
pickupDetails = {
name: "June"
}
this.state.deliveries.forEach((delivery, index) => {
pickupDetails.location = delivery.location;
console.log(pickupDetails)
})
the result of the console:
pickupDetails = {
name: "June"
location: "Japan" //this should be Korea since the first loop data is korea
}
pickupDetails = {
name: "June"
index: "Japan"
}

I think something missing from that code maybe because its dummy data. alright from my point of view you confused with javascript reference.
deliveries: [{ //data of deliveries that I want to pass in pickupDetails
0: {Location: Korea},
1: {Location: Japan}
}]
let pickupDetails = this.state.pickupDetails;
this.state.deliveries.forEach((delivery, index) => {
let newPickupDetails = JSON.parse(JSON.stringify(pickupDetails));
newPickupDetails.location = delivery.location;
console.log(newPickupDetails);
})
the result of the console:
pickupDetails = {
name: "Juan"
location: "Japan" //this should be Korea since the first loop data is korea
}
pickupDetails = {
name: "June"
index: "Japan"
}
JSON.parse and JSON.stringify we use for create new object instead of use reference. console log effected because it linked by reference so if you make it new object it will do.
Check variable newPickupDetails

Related

How to return objects that have matching value when comparing to a separate array

In my state I have an object called foodLog which holds all entries a user enters with one of the keys being foodSelectedKey and I'm trying to return all entries that have a matching value from that key with a different array called foodFilter.
However, this doesn't work and errors out saying foodLog.filter() isn't a function - I've looked this up and it's because it's an Object (I think). Any help would be greatly appreciated!
state = {
// log food is for the logged entries
foodLog: {},
// used for when filtering food entries
foodFilter: [],
};
findMatches = () => {
let foodLog = this.state.foodLog;
let foodFilter = this.state.foodFilter;
let matched = foodLog.filter((item) => {
return foodLog.foodsSelectedKey.map((food) => {
return foodFilter.includes(food);
});
});
};
I guess the reason behind the error Is not a function is that the object can not be looped. By that it means you can not iterate an object with differend variables inside, if it has no index to be iterated like an array. The same goes for map(), find() and similar functions which MUST be run with arrays - not objects.
As far as I understand you have an object named foodLog which has an array named foodsSelectedKey. We need to find intersected elements out of foodFilter with the array. This is what I came up with:
state = {
// log food is for the logged entries
foodLog: {
foodsSelectedKey: [
{ id: 1, name: "chicken" },
{ id: 2, name: "mashroom" }
]
},
// used for when filtering food entries
foodFilter: [
{ id: 1, name: "chicken" },
{ id: 2, name: "orange" }
]
};
findMatches = () => {
let foodLog = this.state.foodLog;
let foodFilter = this.state.foodFilter;
let matched = foodLog.foodsSelectedKey.filter((key) =>
{
for (let i=0; i<foodFilter.length;i++){
if(foodFilter[i].name===key.name)
return true
}
return false;
}
);
return matched;
};
The Output is filtered array, in this case, of one element only:
[{
id: 1
name: "chicken"
}]
In order to check the output - run console.log(findMatches()). Here is the CodeSandbox of the solution. (check console at right bottom)

Insert list data over the iteration(map)

Here I am trying to modify my data over the iteration and send some result to API call.
The API Call receives a request with a structured data format which is
{ list: [{ id: "1", name: "Hello" }, ... ] }
Somehow I managed to call the API with single data ( const params in my current code, it only accepts single data).
But now it has to be done with multiple data something like this:
{ list: [{ id: "1", name: "Hello" }, { id: "22", name: "Ed" }, { id: "36", name: "Jason" } ... ] }
Here is my current code
const [table, setTalbe] = useState(..); // assume, we have some table data here
const processNow = () => {
let id = 0;
let name = '';
// if table length is greater than 1, we go for the loop.
if (table.length >= 1) {
table.map(data => {
id = data.userId;
name = data.userName;
});
//insert table data to params, here I want to add whole table data into "list"
//the final result of this list should be something like this
//ex ) list: [{ id: '123', name: 'Josh' }, { id: '125', name: 'Sue' }, { id: '2222', name: 'Paker' } ...],
// but how??
const params: any = {
list: [
{
id: id,
name: name
},
],
};
//send PUT reqeust with params
axios
.put(
'/api/v1/tosent',
params,
)
.then(res => {
console.log('The response', res);
})
.catch(err => {
console.log('The error: ', err);
});
}
};
but I'm stuck with it, please help me to finish this code to work properly.
need your kind advice.
Array.prototype.map returns a new array with the function you pass applied to every element. You should study the MDN documentation on map to understand its use.
Your current code does nothing with the map return value:
table.map(data => {
id = data.userId;
name = data.userName;
});
You probably assumed .map would mutate the data, as in change it in place. Instead, the whole operation returns a new array.
It looks like you want to do:
const list = table.map(data => {
return {
id: data.userId,
name: data.userName
}
});
This is applying a function to every element in the array that will map each element to a new object, matching your question, with an id and name key. Then it looks like you want to pass the returned value of map (which we named list above) to your call:
const params: any = {
list: list
};

typescript how to find inside an array that is already in an array?

I want to find a value inside an array that is already inside an array.
To give an example of my array:
[
{
ConcessionId: 1,
ConcessionName: "Coyotes",
KnownAs: [
{
TeamId: 1,
Name: "Arizona Coyotes",
},
{
TeamId: 2,
Name: "Phoenix Coyotes",
}
]
},
{
ConcessionId: 2,
ConcessionName: "Devils",
KnownAs: [
{
TeamId: 3,
Name: "Colorado Rockies",
},
{
TeamId: 4,
Name: "New-Jersey Devils",
}
]
}
]
What I want is when Icall my function it returns me the team name.
For example, I the parameter value is 3, I want Colorado Rockies as a name:
public getInfo(_TeamID) {
const concession: ConcessionInfo[] = this.concessionList$.filter(function (x) {
x.KnownAs.filter( (y)=> {
y.TeamId= +_TeamID;
return y.Name;
})
})
}
I try so many different way with filter. But never get something good. Never works.
I can make a double .foreach , for each array. but I think a better method exist than making a double loop.
Thanks
Instead of using the filter method (which is in fact working similar as a for loop), you could do forEach on both arrays. For your current data structure, there is no other way around it.
getInfo = (_TeamID) => {
let teamName = '';
this.concessionList$.forEach(entry => {
entry.KnownAs.forEach(team => {
if(team.TeamId === _TeamID){
teamName = team.Name;
return; // break the loop.
}
})
});
return teamName;
}
Here is a working example
https://stackblitz.com/edit/double-for-lopp
EDIT
If you have a look at the polyfill implementation of filter from Mozilla https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter which is in equivalent to the native implementation of filter, you can see that it is looping through the whole array, the same way as a forEach loop. The difference is that the filter method will return a new array based on the boolean condition inside the callback function, while a forEach loop does not return anything.
Assuming myArray is contains the data you provided.
The following code will work if you're using Typescript 3.7 and above.
public getInfo(teamId: number): string | undefined {
const team = this.concessionList$
.map(concession => concession.KnownAs)
.reduce((a, b) => a.concat(b), [])
.find(team => team.TeamId === teamId)
return team ? team.Name : undefined
}
Usage:
this.getInfo(3) // Colorado Rockies
Ok how this work?
You have to understand what is find. For example:
const result = [{name: 'foo', age: 1}, {name: 'bar', age: 2}]
.find(people => people.name === 'foo')
console.log(result) // {name: 'foo', age: 1}

How to access array element correctly from JSON in Angular 5 app?

I have the following JSON definition:
export class Company {
name: string;
trips : Trip[] = [];
}
I am able to see the trips in the console using:
console.log(this.company);
But I am not able to access the array elements (trip), I've tried
the following:
for(let i = 0; i < this.company.trips.length; i++){
console.log(this.company.trips[i]);
}
When I display the company to the log I'm getting the trip as you can
see below:
{id: 1}
name: "Sample"
trips: {id: 1, r: "ABC"}
id: 1
Any idea how to access array elements in Angular thanks?
Using a combination of Object.keys() and forEach() will let you iterate through the the object in a similar fashion to an array.
explination
const x = {hello: "hi"};
console.log(Object.keys(x)); // will return array looking like
// [hello] which you can run a for each on.
Object.keys(x).forEach(data => {
console.log(x[data]); // will return `hi`
});
Solution
const trips = {id: 1, r: "ABC"}; // const trips = this.company.trips
if (trips) // check the value exists here
{
Object.keys(trips).forEach((data) => {
console.log(trips[data]);
});
}
if(this.company)
this.Company.trips.forEach(x => {
console.log(x);
});

How to update object at specific index in array within React state?

I'm building a calorie counting application using React. One of my components has in its state a list of food items:
this.state = {
items: [
{
name: 'Chicken',
selectedServing: {
label: 'breast, grilled',
quantity: 3
}
},
{
name: 'French Fries',
selectedServing: {
label: 'medium container',
quantity: 1
}
}
]
When a user changes the serving size they consumed, I have to update the properties of the item in the items[] array. For example, if a user ate another chicken breast, I'd need to change the selectedServing object in items[0].
Since this array is part of the component's state, I'm using immutability-helper. I've found that I can properly clone and mutate the state in this way:
let newState = update(this.state, {
items: {
0: {
selectedServing: {
servingSize: {$set: newServingSize}
}
}
}
});
The above code sets the servingSize for the first element in the items[] array, which is Chicken. However, I won't know the index of the object I need to update beforehand, so the 0 I hardcoded won't work. It seems that I can't store this index in a variable, because update() will think it's an object key.
How can I programmatically update an object at a specific index in a list?
An variable can be used as a key of an object.
let foo = 3
let newState = { items: { [foo]: { somthing: 'newValue' } } }
// above is equal to { items: { '3': { somthing: 'newValue' } } }
You can find the index number of 'Chicken' and save it into an variable, and use it to composit newState.

Resources