Vuejs Iterate through a ref object - javascript

I have a small problem,
I get my ref object from that method
const dataAnimals = ref([])
function getDataAnimals() {
axios.get('/json/data_animal.json').then((response) => {
dataAnimals.value = response.data
})
}
getDataAnimals()
And i want to use another method using that ref object :
function countAnimal(type) {
dataAnimals.forEach((item) => {
if (animal.animal == type) {
total_hen += dataMint.value[animal.template_id]
}
return total_hen
})
}
const totalHen = countAnimal('hen')
But i can't iterate through :
dataAnimals.value.forEach((item) => {
Is there anyway to make that work ?
Thank you :)

As the response is an object and not an array, you cannot iterate over it with forEach, you need to use Object.entries()
function countAnimal(type) {
let total = 0;
for (const [key, item] of Object.entries(dataAnimals)) {
if (item.animal === type) {
total++;
}
}
return total;
}
const totalHen = countAnimal('hen');
And I would use a reactive object:
const dataAnimals = ref(null);
function getDataAnimals() {
axios.get('/json/data_animal.json').then((response) => {
dataAnimals.value = response.data
});
}
getDataAnimals()
Of course if you want that count to be reactive as well you'd need to use a computed property.

Related

How to change field from return response in api

This is the result of response from api
what I want is to change the field return like
_id to id
existing code
WorkflowApi.getTransactionLog().then(logs => {
const newLog = {
...logs,
'id': logs._id
}
}
current result
If you just want to change one specific item, you need to choose it by key - as they are numeric you'll have to use square bracket notation
WorkflowApi.getTransactionLog().then(logs => {
const newLog = {
...logs[43],
'id': logs[43]._id
}
}
If you want to change all of them you'll need to loop
WorkflowApi.getTransactionLog().then(logs => {
const newLogs = Object.fromEntries(Object.entries(logs).map( ([k,v]) => {
return [k, {
...v,
'id': v._id
}]
}))
}
For removing a key I would suggest something like this:
const objectWithoutKey = (object, key) => {
const {[key]: deletedKey, ...otherKeys} = object;
return otherKeys;
}
console.log(objectWithoutKey({_id:123,id:123},"_id"))

Update array inside object if it exists, otherwise push array to object

If the object is currently in the array I want to update some value, and if it's not I want to add it to the array. This is the solution I have below, which I don't feel is the best/correct way to do it.
const handleAddToCart = product => {
const newList = [...cart]
if (!newList.includes(product)) {
newList.push(product)
} else {
const productIndex = newList.findIndex((obj => obj._id === product._id))
newList[productIndex].prop = "Some value"
}
setCart(newList)
}
Thank you.
You have to be pretty careful here, as there are a few gotchas with object comparison and mutating the state ([...cart] is not sufficient in deep copying cart). You can update the state in a pure fashion as follows, although I would recommend something like Redux for complex state management.
const handleAddToCart = product => {
const index = cart.findIndex(obj => obj._id === product._id)
if (index === -1) {
setCart(cart.concat(product))
} else {
setCart([
...cart.slice(0, index),
Object.assign({}, product, { prop: "Some value" }),
...cart.slice(index + 1),
])
}
}
const handleAddToCart = productToAdd => {
const newList = [...cart];
const existent = newList.find(product => product.id === productToAdd.id);
if(existent) {
existent.prop = "prop";
} else {
newList.push(productToAdd);
}
setCart(newList);
}

Firebase check if an array of values exist before posting in DB

I'm currently building an app using vue.js and firebase as backend and I'm checking whether a value already exists in the database by doing so:
addItem ({commit}, payload) {
const footprint = payload.footprint
firebase.database().ref('ecologic/footprint').once('value', snapshot => {
const obj = snapshot.val()
let objExists
for (let key in obj) {
if (obj[key] === footprint) objExists = true
else objExists = false
}
if (!objExists) {
firebase.database().ref(`ecologic/footprint`).push(footprint)
}
})
},
How can I extend this functionality to compare an array's value with another array and post to firebase if the value doesn't exists yet.
I tried to use double loop but was not working since I'm using a boolean. Is there a nicer way to do it? Thank you
I tried another way but this time console.log is always returning true
firebase.database().ref('ecologic/footprint').once('value', snapshot => {
const objSnap = snapshot.val()
const loadedFootp = []
for (let key in objSnap) {
loadedFootp.push(objSnap[key])
}
for (let obj in footprint) {
const newFootp = footprint[obj]
const objExists = footprint.some((newFootp) => loadedFootp.indexOf(newFootp) !== -1);
console.log(objExists)
}
})
Found a way by doing so:
firebase.database().ref('ecologic/footprint').once('value', snapshot => {
const objSnap = snapshot.val()
const loadedFootp = []
for (let key in objSnap) {
loadedFootp.push(objSnap[key])
}
for (let obj in footprint) {
if (loadedFootp.some(item => item === footprint[obj])) {
} else {
console.log(footprint[obj])
}
}
})

Rewrite a function to find an object by a matching id inside an array, update a value and set a react state

The function below receiving a rating value inside an object. While ID or Question stay intact, the rating value can be updated. As a result a React state value should be updated.
Is there a way to make this function look prettier/concise while just using a vanilla javascript.
ratingCompleted = ({ rating, question, id }) => {
let array = this.state.ratingResponses;
const index = array.findIndex(elem => elem.id == id);
if (index === -1) {
array.push({ rating, question, id });
this.setState({ ratingResponses: array });
} else {
array.map(object => {
if (object.id === id) {
object.rating = rating;
return object;
} else {
return object;
}
});
this.setState({ ratingResponses: array });
}
};
Make sure you spread to stop mutations
This could be a little cleaner but i thought I would show each step.
const array = [...this.state.ratingResponses]; // spread this so as to make a copy
let updatedArray;
const hasRatingAlready = array.some(item => item.id === id);
if (!hasRatingAlready) {
updatedArray = [...array, { rating, question, id }];
} else {
updatedArray = array.map(item => item.id === id ? {...item, rating} : item);
}
this.setState({ ratingResponses: updatedArray });

Return a modified new object from a function

what is the best practice to modify and return a new object from a function?
I wrote the following function :
export const addItemToCart = (currentCart, item) => {
const { name, ...otherProps } = item;
//if item exist in the cart
if (currentCart[name]) {
currentCart[name]["quantity"]++;
return currentCart;
}
//if the item does not exist
else
{
currentCart[name] = { ...otherProps };
currentCart[name]["quantity"] = 1;
return currentCart;
}
// the function must return a new modified object on each call
};
Obviously, the hard-coded property "quantity", and the return statements can definitely be improved.
how can I improve this function to be more readable?
More "readable" is very opinion-based, either way, you can try something like this:
const currentCart = {
hello: {
quantity: 1
}
};
const addItemToCart = (currentCart, item) => {
const { name } = item;
// Short circuit + return the last value
const quantityPrev = currentCart[name] && currentCart[name].quantity;
// Or operator on boolean expression
const quantity = 1 + (quantityPrev || 0);
// Destructing for shallow copy, dynamic key assign
return { ...currentCart, [name]: { quantity } };
};
console.log(addItemToCart(currentCart, { name: 'hello' }));
console.log(addItemToCart(currentCart, { name: 'blazer' }));

Categories

Resources