JSON node undefined as variable - javascript

Using axios to return an object. I'm able to get the keys, etc. In this case, I'm trying to get the value for a child node "Id". When I pass in the Nodes as variables ([trait] [trait2]), I get "undefined". When I pass in [trait].Id it works. What am I doing wrong here? I tried different versions of Arr and Map, but I can't get those to work, but wonder if it's overkill anyway...
var trait = req.params.trait;
var trait2 = req.params.trait2;
axios(config)
.then(function (response) {
const resp_data = JSON.parse(xj.xml2json(response.data, { compact: true, spaces: 2 }));
if ( trait2="" ) {
resp2= resp_data.Application[trait];
} else {
resp2= resp_data.Application[trait];
console.log(resp2);
//CONSOLE RESPONSE:
// {
// Id: { _text: '34A9BCAA-4322-F5AA-9390-1639C06614D2' },
// BudgetedJointInd: { _text: 'Y' },.....
// }
trait2 = String(trait2); //="Id"
console.log(resp2[trait2]); //RETURNS UNDEFINED
//CONSOLE RESPONSE:
//undefined
console.log(resp2.Id); //WORKS CORRECTLY
//CONSOLE RESPONSE:
//{ _text: '34A9BCAA-4322-F5AA-9390-1639C06614D2' }
}
res.status(200).send(resp2.Id); //WORKS CORRECTLY
})
.catch(error => console.error(error))
}

Related

how can I dynamically get the variables in javascript?

I am working on React app, but I think this is most likely JavaScript problem. I have many variables with a pattern, VARIABLE_NAME_{number}, example, FOO_1, FOO_2 ... so on. In my function, it takes index as input and return mapped output.
import power from 'customClass';
const getOneOfFoo = (theIndex) => {
power()
.then(data => {
let result = data?.first?.second?.FOO_{theIndex}?.name ; // how can I declare this one with passing input?
// example, if theIndex=59, I want to have
// let result = data?.first?.second?.FOO_59?.name;
resolve({
result: result
});
})
.catch(err => console.log(err))
});
The data object structure is like this,
data
|-first
|-second
|-FOO_1
|-name
|-FOO_2
|-name
|-FOO_3
|-name
|-FOO_4
|-name
...
In line 5, I want to assign result dynamically. How can I achieve this?
You can treat it like a dictionary.
Here's an example:
const data = {
'FOO_1': { name: 'Kenobi' },
'FOO_2': { name: 'Skywalker' },
'FOO_3': { name: 'Yoda' },
'FOO_4': { name: 'Kylo' },
'FOO_5': { name: 'Sidious' }
}
function getVar(index) {
let result = data?.[`FOO_${index}`]?.name;
return result;
}
console.log(getVar(1)); // expected output: Kenobi
console.log(getVar(2)); // expected output: Skywalker
console.log(getVar(3)); // expected output: Yoda
console.log(getVar(4)); // expected output: Kylo
console.log(getVar(5)); // expected output: Sidious
console.log(getVar(6)); // expected output: undefined
So for your case, it would probably be something like this:
import power from 'customClass';
const getOneOfFoo = (theIndex) => {
power()
.then(data => {
let result = data?.first?.second?.[`FOO_${theIndex}`]?.name;
resolve({
result: result
});
})
.catch(err => console.log(err))
});
And btw, resolve doesn't seem to be defined.
let result = data?.first?.second[`FOO_${theIndex}`]?.name ;
u can use [] with inside is string which is name of property

map method not working at some place using javascript / node js

I have Output in JSON format and i want to specific field from it
{
"id":"01",
"name":"fish",
"Data.id":"f01",
"Data.path":"/home/work/fish.jpg"
}
I am using map function to get the value but the problem is i can only fetch the value of id and name not Data.id and Data.path
so i am getting this value from my database and this is my code by how i am getting the value from database
function runRest(req, res) {
let data = req.body;
Owner.findAll({
raw: true,
where: {
id: data.id,
},
include: {
model: kingdom,
required: false,
},
attributes: ["id", "name"],
})
.then((parents) => {
parents.map((value) => {
console.log(value);
});
})
.catch(function (err) {
console.log(err);
});
}
let value={
"id":"01",
"name":"fish",
"Data.id":"f01",
"Data.path":"/home/work/fish.jpg"
};
value.map((data)=>{
console.log(data.id);
});
I can only fetch data which is in white font color which is ID and name any solution how can i get Data.id and Data.path by using map function
I even tried this
let links = value
.map((child) => {
for (let i in child)
if (i === "Data.id") {
return child[i];
}
})
but i don't want to use this for method any chance I can use Map function ?
The object
values = {
"id":"01",
"name":"fish",
"Data.id":"f01",
"Data.path":"/home/work/fish.jpg"
};
Has the keys: "id", "name", "Data.id", "Data.path"
To get the value "f01" you must use the key "Data.id":
foo = values["Data.id"]; // foo === "f01"
In the comments you mention that you want to map an array of these objects to the data id:
idArray = objects.map(value => value["Data.id"]);

My object javascript is not fully sent to the back

I'm trying to send an object from front to back.
this is my function :
export const addComponent = (newComponent, inputFields) => (dispatch) => {
const url = process.env.REACT_APP_ADD_COMPONENT;
var componentBody = {
type: newComponent.type,
name: newComponent.name,
};
var componentTest = inputFields.map((inputField) => {
return Object.defineProperty(componentBody, inputField.property, {
value: inputField.content,
});
});
console.log(componentTest);
axios
.put(url, componentTest)
.then(dispatch({ type: ADD_COMPONENT, payload: componentTest }))
.catch((err) => {
console.log("Add failed", err);
});
};
When I log componentTest, it get the strucutre that I want, which mean :
{
description: "je décris",
environnement: "j'environne",
name: "test",
type: "Données"
}
But on the backside, in my route when I log req.body, there is only type and name which are present. Like if the defineProperty function doesn't records my object...
I presume that i need to enumerate all the properties of my object, but my knowledges stop here
I founded it,
If someone else need it.
With defineProperty you need to configure your new object by adding :
var componentTest = inputFields.map((inputField) => {
return Object.defineProperty(componentBody, inputField.property, {
value: inputField.content,
writable: true,
enumerable: true,
configurable: true,
});
});
Now i can see my object fully.

Assignment of Nuxt Axios response to variable changes response data content

async fetch() {
try {
console.log(await this.$api.events.all(-1, false)); // <-- First log statement
const res = await this.$api.events.all(-1, false); // <-- Assignment
console.log(res); // <-- Second log statement
if (!this.events) {
this.events = []
}
res.data.forEach((event, index) => {
const id = event.hashid;
const existingIndex = this.events.findIndex((other) => {
return other.hashid = id;
});
if (existingIndex == -1) {
this.events.push(events);
} else {
this.events[existingIndex] = event;
}
});
for (var i = this.events.length - 1; i >= 0; --i) {
const id = this.events[i].hashid
const wasRemoved =
res.data.findIndex((event) => {
return event.hashid == id
}) == -1
if (wasRemoved) {
this.events.splice(i, 1)
}
}
this.$store.commit('cache/updateEventData', {
updated_at: new Date(Date.now()),
data: this.events
});
} catch (err) {
console.log(err)
}
}
// The other functions, maybe this somehow helps
async function refreshTokenFirstThen(adminApi, func) {
await adminApi.refreshAsync();
return func();
}
all(count = -1, description = true) {
const func = () => {
return $axios.get(`${baseURL}/admin/event`, {
'params': {
'count': count,
'description': description ? 1 : 0
},
'headers': {
'Authorization': `Bearer ${store.state.admin.token}`
}
});
}
if (store.getters["admin/isTokenExpired"]) {
return refreshTokenFirstThen(adminApi, func);
}
return func();
},
Both log statements are giving slightly different results even though the same result is expected. But this only happens when is use the function in this specific component. When using the same function in other components, everything works as expected.
First data output:
[
{
"name": "First Name",
"hashid": "VQW9xg7j",
// some more correct attributes
},
{
"name": "Second name",
"hashid": "zlWvEgxQ",
// some more correct attributes
}
]
While the second console.log gives the following output:
[
{
"name": "First Name",
"hashid": "zlWvEgxQ",
// some more correct attributes, but this time with reactiveGetter and reactiveSetter
<get hashid()>: reactiveGetter()
​​ length: 0
​​​​ name: "reactiveGetter"
​​​​ prototype: Object { … }
​​​​<prototype>: function ()
​​​<set hashid()>: reactiveSetter(newVal)
​​​​length: 1
​​​​name: "reactiveSetter"
​​​​prototype: Object { … }
​​​​<prototype>: function ()
},
{
"name": "Second name",
"hashid": "zlWvEgxQ",
// some more correct attributes and still without reactiveGetter and reactiveSetter
}
]
As it can be seen, somehow the value of my hashid attribute changes, when assigning the response of the function call.
The next weird behavior happening here, is that the first object where the hashid field changes also gets reactiveGetter and reactiveSetter (but the second object in the array does not get these).
So it looks to me like something is happening with the assignment that I don't know about. Another guess would be that this has something to do with the Vuex store, because I do not change the Vuex tore in the other place where I use the same function.
It is verified that the backend always sends the correct data, as this is dummy data, consisting of an array with two objects with some attributes. So no other data except this two objects is expected.
Can someone explain to me why this behavior occurs?
There are few problems...
Do not use console.log with objects. Browsers tend to show "live view" of object - reference
this.events.findIndex((other) => { return other.hashid = id; }); is wrong, you are using assignment operator (=) instead of identity operator (===). That's why the hashid of the first element changes...

test case failing due to .map is not a function error

Hi i have a react component expenses-total.js and a corresponding test case expenses-total.test.js as shown below.
expenses-total.js
export default (expenses=[]) => {
if (expenses.length === 0) {
return 0;
} else {
return expenses
.map(expense => expense.amount)
.reduce((sum, val) => sum + val, 0);
}
};
expenses-total.test.js
import selectExpensesTotal from '../../selectors/expenses-total';
const expenses = [
{
id: "1",
description: "gum",
amount: 321,
createdAt: 1000,
note: ""
},
{
id: "2",
description: "rent",
amount: 3212,
createdAt: 4000,
note: ""
},
{
id: "3",
description: "Coffee",
amount: 3214,
createdAt: 5000,
note: ""
}
];
test('Should return 0 if no expenses', ()=>{
const res = selectExpensesTotal([]);
expect(res).toBe(0);
});
test('Should correctly add up a single expense', ()=>{
const res = selectExpensesTotal(expenses[0]);
expect(res).toBe(321);
});
test('Should correctly add up multiple expenses',()=>{
const res = selectExpensesTotal(expenses);
expect(res).toBe(6747);
});
when i run the test case, its getting failed by giving an error
TypeError: expenses.map is not a function
I know the test case is correct but dont know what is wrong with thecomponent.
Could anyone please help me in fixing this error?
The problem is with if (expenses.length === 0) and the test case that uses selectExpensesTotal(expenses[0]):
expenses[0] passes an object, which has no length property, so in the function being tested, expenses.length returns undefined. However, undefined === 0 evaluates to false so your code goes into the else block tries to use .map on the object, which doesn't have that function, thus it throws an error.
In a brief: you can't map over an object.
expenses is an array of objects, so expenses[0] is an object.
Condition expenses.length === 0 evaluates to false, since obviously .length property does not exist on Object.prototype, so the else condition takes place - your function tries to map over an object.
The problem is that expenses[0] is an object (you probably expected it to be an array) and an object does not have a map function. A quick hack would be to add another ifs into the loop to check if expenses is actually an object. So that:
export default (expenses=[]) => {
if (expenses.length === 0) {
return 0;
} else {
if (typeof expenses === 'object') {
return expenses.amount
} else {
return expenses
.map(expense => expense.amount)
.reduce((sum, val) => sum + val, 0);
}
}
};
I hope this help.
To fix this error, you can pass in an array of object into
selectExpensesTotal([expenses[0]])
rather than just an object
selectExpensesTotal(expenses[0])
So your code show look like this:
test('Should correctly add up a single expense', ()=>{
const res = selectExpensesTotal([expenses[0]]);
expect(res).toBe(321);
});
.map function will now work on expenses. Because, this is now an array of object ( works with map function ) and not an object(This does not work with map function)

Categories

Resources