I have a function which returns an object with properties only which are defined.
How to refactor the function so that I don't need to make if clauses for every parameter value? There must be more elegant way to do this.
const getQuery = ({ foo, bar, zoo }) => {
const query = {};
if (foo) {
query.foo = foo;
}
if (bar) {
query.bar = bar;
}
if (zoo) {
query.zoo = zoo;
}
return query;
}
I would do something like
function getQuery(obj){
// filter the accepted keys
var filtered = Object.keys(obj).filter((k) => ~["foo", "bar", "baz"].indexOf(k))
// construct new object with filtered keys
var query = {}
filtered.forEach((k) => query[k] = obj[k])
return query
}
Here's a basic function that will copy only properties provided in the wantedProps array. It will not mutate the original object.
let filterProperties = (originalObject = {}, wantedProps = []) =>
{
let filteredObject = {};
wantedProps.forEach( val => filteredObject[val] = originalObject[val] );
return filteredObject;
}
If you're just trying to filter out undefined vals then you could do:
obj => {
let newObject = {}
Object.keys(obj).forEach(key => {
if(obj[key] !== undefined) newObject[key] = obj[key];
})
return newObject;
}
Related
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.
How can I copy a list of properties from a object to another skipping the null or undefined values?
Something like this
const obj1 = { prop1: 'value', prop2: undefined }
const obj2 = copy(obj1, ['prop1', 'prop2', 'prop3']) // prop3 doesn't exist and prop2 should be excluded
console.log(obj2) // should print { prop1: 'value' }
Here using Object.fromEntries() and Array.prototype.filter().
see: Object.fromEntries(): Object transformations
const obj1 = { prop1: 'value', prop2: undefined }
const copy = (obj, props) => {
return Object.fromEntries(Object.entries(obj)
.filter(([k, v]) => (
(props.includes(k) && v !== undefined && v !== null)
)));
}
const obj2 = copy(obj1, ['prop1', 'prop2', 'prop3'])
console.log(obj2)
Try this:
const obj1 = { prop1: 'value', prop2: undefined }
function copy(obj1, props)
{
return props.reduce(
(acum, current) =>
(obj1[current] !== undefined && obj1[current] !== null) ?
({...acum, [current]:obj1[current]}):
acum
,{}
)
}
const obj2 = copy(obj1, ['prop1', 'prop2', 'prop3']) // prop3 doesn't exist and prop2 should be excluded
console.log(obj2) // should print { prop1: 'value' }
function copy(object, keys) {
const clone = {};
for(const key of keys) {
if(!isNaN(object[key])) clone[key] = object[key];
}
return clone;
}
It's not clear what the purpose of the array is in your code, but this should work for the problem as you stated it. It reduces over the entries of the original object with a new object as an accumulator, and only copies over properties with defined values. To include null in the check, you can change the condition to be != null (because undefined == null).
const copyExcludingUndefined = (obj = {}) =>
Object.entries(obj)
.reduce((a, [k, v]) => {
if (v !== undefined) {
a[k] = v
}
return a
}, {})
Write your own copy function :)
let copy = function(o, args) {
let obj = {};
if (Array.isArray(args)) {
args.forEach(arg => {
if(o[arg] !== undefined) {
obj[arg] = o[arg];
}
});
}
return obj;
}
I have a filter component which user can choose any data to filter so I store this data in state.when I want to create a params for query some of the field not choosen by user I only wanna get the one which has value here is the code ;
function createParams(params = {}) {
let result = "?";
for (let key in params) {
result += `${key}=${params[key]}&`;
}
return result;
}
export async function callApi(params) {
const parameters = createParams(params);
try {
const response = await fetch(URL+ parameters);
const res = await response.json();
return res;
} catch (error) {
console.error(error)
throw error;
}
}
export const requestProperties = (params) => callApi(params);
const requestedParams = {type:"Fiat", model:"500", color:""};
I only want to get the type and model because it has been choosen by user to filter. I dont wanna include the colour
Thank you..:)
You can take entries and then filter out the records.
var requestedParams = {type:"Fiat", model:"500", color:""};
var result = Object.fromEntries(Object.entries(requestedParams).filter(([k,v])=>v));
console.log(result);
You can destructure the object if you only want to exclude one key-value pair
const requestedParams = {type:"Fiat", model:"500", color:""};
const exclude = 'color';
const {[exclude]: remove, ...rest} = requestedParams;
console.log(rest);
If you have multiple key-value pairs that you want to exclude, you can use reduce function
const requestedParams = { type: "Fiat", model: "500", color: "" };
const res = Object.entries(requestedParams).reduce((acc, curr) => {
return curr[1] ? (acc[curr[0]] = curr[1], acc) : acc;
}, {});
console.log(res);
As a part of a challenge I need to implement the .findKey() method myself. Below is the solution proposition, however, I get an error "predicate is not a function".
const _ = {
findKey(object, predicate) {
for (let key in object) {
let value = object[key];
let predicateReturnValue = predicate(value);
if (predicateReturnValue) {
return key;
};
};
undefined
return undefined;
}
};
Can anyone help?
function findKey(object, predicate) {
for (let key in object) {
let value = object[key];
let predicateReturnValue = predicate(value);
if (predicateReturnValue) { // just take the value
return key; // return key
}
}
}
const isEqual = a => b => a === b
const object = { a: 'Apple', b: 'Beer', c: 'Cake' }
alert(findKey(object, isEqual('Apple')));
alert(findKey(object, isEqual('Cakes')));
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' }));