I have a method
{payload.find((item) => item.dataKey === 'value')?.value || '-'}
and that's my payload that I pass normally as an array to the component with the method above, but it always returns the '-' sign:
export const mockedResponse = {
area: 'test',
bestValue: null,
comments: 'test comments',
controllerOnOffStatus: 'test',
currentValue: 1,
description: 'test description',
id: 'test id',
kind: 'test',
payload: [payload],
};
const payload = {
avg: 11,
timestamp: '22:00',
value: 11.07,
};
Any ideas why it cannot find the value? How should the mockedResponse look like, so the method would work?
You can not use a find() method for the objects. As your payload is an object like
const payload = {
avg: 11,
timestamp: '22:00',
value: 11.07,
};
And you want to check if the value key exists in the payload object, and if so return that value, otherwise return '-', you can use the following
payload.value || '-'
After your editing, I can see that you have converted the payload to the array.
You didn't have the dataKey property in the payload. If you want to check if the value exists in the item please try the following
{payload.find((item) => item.value)?.value || '-'}
Related
I am using Zustand in a Next.js app using TypeScript,
For some reason, I get a runtime error message whenever I try to iterate on my state object.
The structure of my car damaged zone object is:
const damagedZones = {
Left: {
front_door:[
{
id: 1,
picture1: 'picture 1 base64 string',
picture2: 'picture 2 base64 string',
comment: 'any comment'
},
{
id: 2,
picture1: 'picture 1 base64 string',
picture2: 'picture 2 base64 string',
comment: 'any comment'
}
],
back_door: [
],
so, imagine I add a new object to my "front_door" array, here is my zustand store and function:
In the code below, the dynamic prop "zone" would be my "Left" key of my damagedZones object, and the dynamic prop "element" would be my "front_door" key.
export const useDamagedZones = create<DamagedZonesProps>((set) => ({
damagedZones: damagedZones,
setDamagedZones: (elementItem: damagedItem, zone: string, element: string) => {
set(state => ({
damagedZones: {
...state.damagedZones,
[zone]: {
...state.damagedZones[zone],
[element]: [
...state.damagedZones[zone]?.[element],
elementItem
]
}
}
}))
},
}))
so basically when I trigger this function, I get a runtime error which says:
TypeError: Invalid attempt to spread non-iterable instance.
In order to be iterable, non-array objects must have a Symbol.iterator method.
I am not understanding why that is so....
I have tried using an object instead of an array, with an id as key, and it works fine, but it's not super convenient, so an array is the best in this situation, but it doesn't perform as expected....
Alright i figured it out, it is because i misconceived my typescript types for my damagedZone object ! i forgot to mention that one key would be an array :)
it works now that my object type is like so :
type damagedItem = {
id?: number
picture1?: string | null,
picture2?: string | null,
picture3?: string | null,
comment?: string,
}
type DamagedElement = {
[key: string]: damagedItem[]
}
type DamagedZone = {
step1_gauche: DamagedElement,
step1_droite: DamagedElement,
step1_avant: DamagedElement,
step1_arriere: DamagedElement
}
and here is the store useDamagedZones for now :
export const useDamagedZones = create<DamagedZonesProps>((set) => ({
damagedZones: damagedZones,
setDamagedZones: (elementItem: damagedItem, zone: string, element: string) => {
set(state => ({
damagedZones: {
...state.damagedZones,
[zone]: {
...state.damagedZones[zone],
[element]: [
...state.damagedZones[zone]?.[element],
elementItem
]
}
}
}))
},
removeDamagedItem : (zone: string, element: string, id: number ) => {
set(state => ({
damagedZones: {
...state.damagedZones,
[zone]: {
...state.damagedZones[zone],
[element]:
state.damagedZones[zone]?.[element].filter(el => el.id !== id)
}
}
}))
}
}))
I have the following JSON object
[
{
'parameter-name': 'device',
enabled: true,
value: '077743322L102515',
description: 'device identifier. Should be used only when multiple devices are connected at once'
},
{
'parameter-name': 'app_id',
enabled: true,
value: 'com.instagram.andrpbj',
description: ' when using this parameter, you are able to use Insomniac on a cloned Instagram-application. Just provide the new package name'
},
{
'parameter-name': 'old',
enabled: false,
value: 'True',
description: 'add this flag to use an old version of uiautomator. Use it only if you experience problems with the default version'
}
]
i wanted to access the value of the parameter-name: 'old', by value i mean value
is there a one step solution to do that without iterating through each entry ?
From my point of view, using Array.find() is the cleanest solution to get the value:
const { value } = data.find((obj) => obj['parameter-name'] === 'old');
If your goal is to edit the value as you're asking in the comment, you can get the index of the targeted object within the array using Array.findIndex() and then edit the data:
const objIdx = data.findIndex((obj) => obj['parameter-name'] === 'old');
data[objIdx].value = 'newValue'
Instead of getting the index, you could even manipulate the value on the object directly:
const obj = data.find((obj) => obj['parameter-name'] === 'old');
obj.value = 'newValue';
Code Snippet
const data = [{
'parameter-name': 'device',
enabled: true,
value: '077743322L102515',
description: 'device identifier. Should be used only when multiple devices are connected at once'
},
{
'parameter-name': 'app_id',
enabled: true,
value: 'com.instagram.andrpbj',
description: ' when using this parameter, you are able to use Insomniac on a cloned Instagram-application. Just provide the new package name'
},
{
'parameter-name': 'old',
enabled: false,
value: 'True',
description: 'add this flag to use an old version of uiautomator. Use it only if you experience problems with the default version'
}
];
const obj = data.find((obj) => obj['parameter-name'] === 'old');
obj.value = 'newValue';
console.log(data);
In order to account for a situation where the 'searched-value' is not found, it may be better to split the assignment like this:
const foundObj = data?.find((obj) => obj['parameter-name'] === 'old');
if (foundObj) foundObj.value = 'newValue';
const data = [{
'parameter-name': 'device',
enabled: true,
value: '077743322L102515',
description: 'device identifier. Should be used only when multiple devices are connected at once'
},
{
'parameter-name': 'app_id',
enabled: true,
value: 'com.instagram.andrpbj',
description: ' when using this parameter, you are able to use Insomniac on a cloned Instagram-application. Just provide the new package name'
},
{
'parameter-name': 'old',
enabled: false,
value: 'True',
description: 'add this flag to use an old version of uiautomator. Use it only if you experience problems with the default version'
}
];
const foundObj = data?.find((obj) => obj['parameter-name'] === 'old');
if (foundObj) foundObj.value = 'newValue';
console.log(data);
An alternative to Alexander's answer if you don't want to mutate the array object directly.
It's a very generic function that accepts a query object (key, oldValue, newValue) so it will work on all the property keys, not just parameter-name.
It finds the object that matches the query criteria (if nothing is found the function returns null), filters out the objects that don't match the query criteria, and then returns that filtered array with a new updated object.
const arr=[{"parameter-name":"device",enabled:!0,value:"077743322L102515",description:"device identifier. Should be used only when multiple devices are connected at once"},{"parameter-name":"app_id",enabled:!0,value:"com.instagram.andrpbj",description:" when using this parameter, you are able to use Insomniac on a cloned Instagram-application. Just provide the new package name"},{"parameter-name":"old",enabled:!1,value:"True",description:"add this flag to use an old version of uiautomator. Use it only if you experience problems with the default version"}];
// Accept an array, and a query object
function change(arr, query) {
// Destructure the query
const { key, oldValue, newValue } = query;
// Look for the object where the value
// of the key specified in the query
// matches the oldValue
const found = arr.find(obj => {
return obj[key] === oldValue;
});
// If there isn't a match return null
if (!found) return null;
// Otherwise `filter` out the objects that
// don't match the criteria...
const filtered = arr.filter(obj => {
return obj[key] !== oldValue;
});
// Destructure all the object properties
// away from the property we want to update
const { [key]: temp, ...rest } = found;
// Return a new array with a new updated object
return [ ...filtered, { [key]: newValue, ...rest } ];
}
const query = {
key: 'parameter-name',
oldValue: 'old',
newValue: 'new'
};
console.log(change(arr, query));
const query2 = {
key: 'value',
oldValue: '077743322L102515',
newValue: '999999999'
};
console.log(change(arr, query2));
data.filter((value) => {
if(value['parameter-name'] === 'old'){
console.log(value);
}
})
I have the following array that has been generated by the DocuSign API:
const signers = [
exports {
email: 'email1#gmail.com',
name: 'Test Name One',
recipientId: 'signer_1',
routingOrder: '1'
},
exports {
email: 'email2#gmail.com',
name: 'Test Name Two',
recipientId: 'signer_2',
routingOrder: '2'
},
exports {
email: 'email3#gmail.com',
name: 'Test Name Three',
recipientId: 'signer_3',
routingOrder: '3'
}
]
I need to get the index of the object in this array where the recipientId === 'signer_2' (for example), and have tried the following:
const signerKey = signers.filter(signerObj => {
console.log(signerObj) // returns "exports { ...email, name, etc }"
console.log(Object.keys[signerObj]) // returns undefined
console.log(signerObj.exports.recipientId) // returns undefined
console.log(typeof signerObj) // returns object
return signerObj.recipientId === 'signer_2' // returns undefined
})
How do I deal with finding data within these exports since they're not actual objects?
For some reason when I used JSON.stringify() then JSON.parse I was able to process everything normally:
const stringified = JSON.stringify(signers)
const signersObject = JSON.parse(stringified)
#casenonsensitive recommended using the lo-dash framework, which I haven't looked into yet, but could be a better solution.
I have a problem in pushing input into array. I have an array with some properties and I'm going to push some value into it, but I have no idea how to tell which value is for which property.
This is my array that I want to push into it:
validInput: [{
image: avatar1,
name: '',
email: '',
passwrod: '',
phone: '',
revenue: '',
create_date: '',
age: '',
id: ''
}]
This is my function that pushes into the array:
validation(value, REGEX) {
if (REGEX.test(value) === true) {
this.state.validInput.push(value);
this.setState({
validInput: this.state.validInput
});
} else {
console.log('error');
}
}
If I understood correctly and you wish to convert your object inside validInput array into an array of objects you can do this:
Let's say we are looking to get an array of objects with the following format:
{keyName:key,keyValue:value}
we can do something like that:
const newArray = new Array();
Object.keys(this.validInput[0])
.forEach(singleKey => {
newArray.push({
keyName:singleKey,
keyValue:this.validInput[0][singleKey]
})
})
// finally - we will have the newly formatted array in newArray
I think you should have some unique way of identifying the object you want for filtering process like id, name etc. For modified function,
validation(id, value, REGEX) {
if(REGEX.test(value)){
this.state.validInput.map((user) => {
if(user.id === id) {
user.PROPERTY_YOU_NEED_TO_UPDATE = value
}
}
}
}
Since this validInput might receive another object better use to identify it using if(user.id === id). If validInput won't receive another there is no point to use array of objects.
validInput: {
image: avatar1,
name: '',
email: '',
passwrod: '',
phone: '',
revenue: '',
create_date: '',
age: '',
id: ''
}
If it's like above you can just edit the property you want...
this.setState(state => {
let user = Object.assign({}, state.validInput);
user.PROPERTY_YOU_NEED_TO_UPDATE = value;
return { user };
})
This is my code for collating items in preparation for submission to a RESTful API:
let mergeLinesData = this.incomingStepsData.map((item) => ({
dataStepId: _.get(item, 'stepId'),
dataStepName: _.get(item, 'stepName'),
name: _.get(item, 'itemName')
}));
However some users may not have yet defined a name so I would like to fall back and set a default value for name at this point.
How can I provide a default value as I would with javascript variables such as
fruit = fruit || "strawberry";
And how can that default value be a concatenation of dataStepName + "-" + dataStepId?
Just add a conditional statement to your code like in your example:
name: _.get(item, "itemName") || `${dataStepName}-${dataStepId}`)
Alternatively, use the third parameter of _.get():
name: _.get(item, "itemName", `${dataStepName}-${dataStepId}`)
I think it is easier to do it with js , rather than using lodash for it. You can use destructuring.
let mergeLinesData = this.incomingStepsData.map(({stepId, stepName, itemName}) => ({
dataStepId: stepId,
dataStepName: stepName
name: itemName || `${stepName}-${stepId}`
}));
You can use destructuring with alias, and default value:
const incomingStepsData = [{ stepId: 1, stepName: 'step1', name: 'name1' }, { stepId: 2, stepName: 'step2' }];
const mergeLinesData = incomingStepsData.map(({
stepId: dataStepId,
stepName: dataStepName,
name: itemName = `${dataStepName}-${dataStepId}`
}) => ({
dataStepId,
dataStepName,
itemName
}));
console.log(mergeLinesData);