I've got an object of type : [ {name : 'xxx' , price: '555', quantity : '2' } , {...} ] and so one.
I got a class
getCartItems() {
let items = localStorage.getItem('item');
items = JSON.parse(items);
return items;
}
where i get this array.
Now i am getting index of the array, for example 0 , it should remove first array from object.
but when i do .remove, or other, it does not work. this.getCartItems()[index].remove or other does not work. Can you help me?
My guess is that you are mutating the object after you parse it and you never save it back.
You have to save the mutated object inside of your localStorage to make your removal of the first item persistant.
Look at the following example :
const localStorage = {
items: {
item: JSON.stringify([{
name: 'xxx',
price: '555',
quantity: '2',
}, {
name: 'yyy',
price: '666',
quantity: '5',
}, {
name: 'zzz',
price: '777',
quantity: '6',
}]),
},
getItem: str => localStorage.items[str],
setItem: (str, value) => {
localStorage.items[str] = value;
},
};
function getCartItems() {
const items = localStorage.getItem('item');
const parsedItems = JSON.parse(items);
// We remove the first element
const item = parsedItems.splice(0, 1);
// We save the value
localStorage.setItem('item', JSON.stringify(parsedItems));
return item;
}
console.log('First call ---');
console.log(getCartItems());
console.log('');
console.log('Second call ---');
console.log(getCartItems());
console.log('');
console.log('Third call ---');
console.log(getCartItems());
Use filter to get required items. In the following updated will not have earlier 0 index item. Now, the updated array you may want to set in localStorage again if required.
const items = getCartItems();
const indexToRemove = 0;
const updated = items.filter((,index) => index !== indexToRemove);
You can use array method filter to remove the object from array. This can look something like this:
getCartItems() {
let items = localStorage.getItem('item');
items = JSON.parse(items);
return items;
}
removeCart(){
return id; // the id that you will have from your a tag
}
const updatedItems = this.getCartItems().filter((item,index) => index !== this.removeCart()); // in updated items you will find your filtered out array of object
Related
I am trying to create a series of new objects using the values from an existing object to push to my database.
Here is the existing object:
{
name: 'Pasta',
method: 'Cook pasta',
ingredients: [
{ measure: 'tbsp', quantity: '1', ingredient_name: 'lemon' },
{ measure: 'g', quantity: '1', ingredient_name: 'salt' },
{ measure: 'packet', quantity: '1', ingredient_name: 'spaghetti' },
{ measure: 'litre', quantity: '1', ingredient_name: 'water' }
]
}
Basically I have a function that inserts and returns the id of the recipe into one table, then inserts and returns/or finds the ids of the relevant ingredients and the final part (with which I am struggling) is to combine the returned recipe_id, ingredient_id and the correct measure and quantity (as written in the object above).
Here is where I have gotten to:
//starting point is here
async function addNewRecipe(newRecipe, db = connection) {
console.log(newRecipe)
const recipeDetails = {
recipe_name: newRecipe.name,
recipe_method: newRecipe.method,
}
const ingredientsArray = newRecipe.ingredients
const [{ id: recipeId }] = await db('recipes')
.insert(recipeDetails)
.returning('id')
const ingredientsWithIds = await getIngredients(ingredientsArray) //returns an array of ids
ingredientsWithIds.forEach((ingredientId) => {
let ingredientRecipeObj = {
recipe_id: recipeId, //works
ingredient_id: ingredientId, //works
measure: newRecipe.ingredients.measure, //not working - not sure how to match it with the relevant property in the newRecipe object above.
quantity: newRecipe.ingredients.quantity,//not working - not sure how to match it with the relevant property in the newRecipe object above.
}
//this is where the db insertion will occur
})
}
The desired output would be:
ingredientRecipeObj = {
recipe_id: 1
ingredient_id: 1
measure: tbsp
quantity: 1
} then insert this into db
followed by:
ingredientRecipeObj = {
recipe_id: 1
ingredient_id: 2
measure: g
quantity: 1
} then insert into db
etc. etc.
The problem seems to be that the function "getIngredients" returns only the IDs. Once you have fetched them, you have no way of knowing which ID is for which ingredient. One way to change that is to make the method return an array of both the ID and the ingredient name. Then you could match them like this:
const ingredientsWithIds = await getIngredients(ingredientsArray) //now an array of objects with ingredient_name and id
ingredientsWithIds.forEach((ingredient) => {
const recipeIngredient = ingredientsArray.find(ri => ri.ingredient_name === ingredient.ingredient_name)
const ingredientRecipeObj = {
recipe_id: recipeId,
ingredient_id: ingredient.id,
measure: recipeIngredient.measure,
quantity: recipeIngredient.quantity,
}
//this is where the db insertion will occur
})
Since you haven't posted the "getIngredients" function it is hard to say exactly how to adapt it to return the name as well.
this is my code
const [state, setState] = useState(
[{id: 1, key:""}, {id: 2, key:""}, {id: 3, key:""}]
)
i want to to change "key" state
im confuse
now im using
setState(
[...state].map((data, index) => {
if (data.id === state[index].id) {
return {
...data,
key: result,
};
} else return data;
}),
);
}
result variable came from result when i fetching data.
result is a random string
If your data structure is always going to be in that order data.id === state[index].id doesn't really achieve much.
For example:
when data.id is 1 the index will be 0. And state[0].id is 1.
when data.id is 2 the index will be 2. And state[1].id is 2.
etc.
It just sounds like you want to iterate over all the objects in state and update each key value with that random string you mentioned in the comment section. There's no need to make a copy of state since map already returns a new array ready for setState to use.
function setState(mapped) {
console.log(mapped);
}
const state = [{ id: 1, key: '' }, { id: 2, key: '' }, { id: 3, key: '' }];
const result = 'random';
const mapped = state.map(data => {
return { ...data, key: result };
});
setState(mapped);
If we have an array that contains objects that each contain and array of tags like shown below:
const arr = [
{
0: {
name: 'Apple',
tags: ['fruit', 'green']
}
},
{
1: {
name: 'ball',
tags: ['round']
}
},
{
2: {
name: 'cat',
tags: ['grey', 'meow', 'treats']
}
}
];
Is it possible to use react hooks to update the array of tags? I was trying something like this but got confused:
setArr((prev =>
([...prev,
({...prev[id],
[...prev[id]['tags'],
prev[id]['tags']: newArrOftags ]})],
));
Here's the simplest syntax that I would use to target a specific item in your array, given you know the number value used within that item, and then update the previous state within your useState hook:
const lookup = 1; // Using the correct number value to target ball
const newItem = 'Additional ball tag here';
setArr((prevArr) => {
const newArr = prevArr.map((item) => {
if (item[lookup]) {
item[lookup].tags = [...item[lookup].tags, newItem];
}
return item;
});
return newArr;
});
Instead of using short hand syntax which is a bit complex in your case, here is what you need. I am looping through the array using map and finding the object with id. Then appending the tags to that object's tags array. In the example I am adding a few tags to an object with id 1.
let arr = [
{
0: {
name: 'Apple',
tags: ['fruit', 'green']
}
},
{
1: {
name: 'ball',
tags: ['round']
}
},
{
2: {
name: 'cat',
tags: ['grey', 'meow', 'treats']
}
}
];
const id = 1;
const tags = ["test1","test2","test3"]
arr = arr.map((a)=>{
if(Object.keys(a).includes(id.toString()))
{
a[id].tags = [...a[id].tags,...tags];
}
return a;
})
Use the above logic instead of spread operator to set state. map returns a new array so it's safe to use for state updates.
Here is an example of the logic: https://stackblitz.com/edit/js-xqnjai
In my post request I need to pass an array with an object inside it.
when I tried to add new properties inside an object its adding.
but when I tried to add when an object is present inside an array its not adding.
I have sportsvalues as array const sportsValues = [{ ...values }];
I am trying to build something like this, so that I can pass in the api
[
{
"playerName": 3,
"playerHeight": 1
}
]
can you tell me how to fix it.
providing my code snippet below.
export function sports(values) {
const sportsValues = [{ ...values }];
sportsValues.push(playerName:'3');
console.log("sportsValues--->", sportsValues);
// sportsValues.playerName = 3//'';
// sportsValues.playerHeight = 1//'';
console.log("after addition sportsValues--->", sportsValues);
console.log("after deletion sportsValues--->", sportsValues);
return dispatch => {
axios
.post(`${url}/sport`, sportsValues)
.then(() => {
return;
})
.catch(error => {
alert(`Error\n${error}`);
});
};
}
Since sportsValues is an array of objects, you can push new object into it. Check out code below.
const sportsValues = [];
sportsValues.push({
playerName:'3',
playerHeight: 1,
});
console.log(sportsValues);
I don't fully understand what you're trying to do, but here's some pointers:
If you're trying to update the object that's inside the array, you first have to select the object inside the array, then update it's attribute:
sportsValues[0].playerName = 3
although, I recommend building the object correctly first, then passing it to the array, it makes it a little easier to understand in my opinion:
const sportsValues = [];
const firstValue = { ...values };
firstValue.playerName = '3';
sportsValues.push(firstValue);
or
const firstValue = { ...values };
firstValue.playerName = '3';
const sportsValues = [firstValue];
or
const sportsValues = [{
...values,
playername: '3',
}];
if you're trying to add a new object to the array, you can do this:
const sportsValues = [{ ...values }];
sportsValues.push({ playerName: '3' });
etc...
Array.push adds a new item to the array, so in your code, you're going to have 2 items because you assign 1 item at the beginning and then push a new item:
const ar = [];
// []
ar.push('item');
// ['item']
ar.push({ text: 'item 2' });
// ['item', { text: 'item 2' }]
etc...
export function sports(values) {
const sportsValues = [{ ...values }];
sportsValues.push(playerName:'3');
let playerName='3'
sportsValues.playerName= playerName; // you can bind in this way
console.log("sportsValues--->", sportsValues);
return dispatch => {
axios
.post(`${url}/sport`, sportsValues)
.then(() => {
return;
})
.catch(error => {
alert(`Error\n${error}`);
});
};
}
What is the best way to filter out data that exists within an object?
I was able to do use the below code when data was just an array of values but now I need to filter out any data where the item.QID exists in my array of objects.
Data Obj:
var data = [{
QID: 'ABC123',
Name: 'Joe'
},
{
QID: 'DEF456',
Name: 'Bob
}]
Snippet:
// I don't want to include data if this QID is in my object
this.employees = emp.filter(item =>!this.data.includes(item.QID));
From what I understand, includes only works on an array so I need to treat all of the QID values in my object as an array.
Desired Outcome: (assuming item.QID = ABC123)
this.employees = emp.filter(item =>!this.data.includes('ABC123'));
Result:
var data = [{
QID: 'DEF456',
Name: 'Bob'
}]
UPDATE:
Apologies, I left some things a little unclear trying to only include the necessary stuff.
// People Search
this.peopleSearchSub = this.typeahead
.distinctUntilChanged()
.debounceTime(200)
.switchMap(term => this._mapsService.loadEmployees(term))
.subscribe(emp => {
// Exclude all of the current owners
this.employees = emp.filter((item) => item.QID !== this.data.QID);
}, (err) => {
this.employees = [];
});
The above code is what I am working with. data is an object of users I want to exclude from my type-ahead results by filtering them out.
The question is a little ambiguous, but my understanding (correct me if I'm wrong), is that you want to remove all items from a list emp that have the same QID as any item in another list data?
If that's the case, try:
this.employees = emp.filter(item => !this.data.some(d => d.QID === item.QID))
some is an array method that returns true if it's callback is true for any of the arrays elements. So in this case, some(d => d.QID === item.QID) would be true if ANY of the elements of the list data have the same QID as item.
Try Object#hasOwnProperty()
this.employees = emp.filter(item =>item.hasOwnProperty('QID'));
You can use a for ... in to loop through and filter out what you want:
const data = [{
QID: 'ABC123',
Name: 'Joe'
},
{
QID: 'DEF456',
Name: 'Bob'
}]
let newData = [];
let filterValue = 'ABC123';
for (let value in data) {
if (data[value].QID !== filterValue) {
newData.push(data[value]);
}
}
newData will be your new filtered array in this case
You can use an es6 .filter for that. I also added a couple of elements showing the filtered list and an input to allow changing of the filtered value. This list will update on the click of the button.
const data = [{
QID: 'ABC123',
Name: 'Joe'
},
{
QID: 'DEF456',
Name: 'Bob'
}]
displayData(data);
function displayData(arr) {
let str = '';
document.getElementById('filterList').innerHTML = '';
arr.forEach((i) => { str += "<li>" + i.QID + ": " + i.Name + "</li>"})
document.getElementById('filterList').innerHTML = str;
}
function filterData() {
let filterValue = document.getElementById('filterInput').value;
filterText (filterValue);
}
function filterText (filterValue) {
let newArr = data.filter((n) => n.QID !== filterValue);
displayData(newArr)
}
<input id="filterInput" type="text" value="ABC123" />
<button type ="button" onclick="filterData()">Filter</button>
<hr/>
<ul id="filterList"><ul>