Can't retrieve object property in Javascript - javascript

Currently, I'm trying to retrieve a particular property from a javascript object returned by mongoose.
I can see the property when printing the whole object, but when trying to use it, I get an undefined. Here's the code:
Match.findOne({id: match.id}, function (err, match) {
console.log(match)
console.log(typeof match)
console.log(match.id)
console.log(match.winner)
})
The output of that is:
{ _id: 552c7f2925efcbc88ccc55bf,
id: 499142595,
region: 'br',
winner: 200,
championsLose: [ 25, 96, 81, 113, 63 ],
championsWin: [ 37, 238, 201, 268, 81 ]
}
object
499142595
undefined
Even though the 'winner' property is clearly there.
Any ideas?
UPDATE: added more logging to the above code and results of it

It's odd that there are no quotes around the value of associated with the key "_id":
{ _id: 552c7f2925efcbc88ccc55bf, // should be --> "552c7f2925efcbc88ccc55bf"
id: 499142595,
region: 'br',
winner: 200,
championsLose: [ 25, 96, 81, 113, 63 ],
championsWin: [ 37, 238, 201, 268, 81 ]
}
This seems to indicate that it is not actually an object. Which, of course, explains why match.winner is undefined. I would do console.log(typeof match) and see what it says.

console updates("Live Update") the last references if the object/property is change even after console.log(). i have recently got this pain using chrome
it might be the case
check this example in chrome, dont know how this problem behaves in node console or the tool you are using
obj = {a:"b",b:"c"};
console.log(obj); // logs Object { b: "c" } not {a:"b",b:"c"}
delete obj.a;
console.log(obj);// logs Object { b: "c" }
you might have deleted the match.winner property later in the code. that seems to be the case only

Finally the issue wasn't in that piece of code, but in the Model definition. The variable name wasn't updated properly, so the old name was still being used there:
var mongoose = require('mongoose');
module.exports = mongoose.model('Match',{
id: Number,
region: String,
championsWin: Array,
championsLose: Array,
winnerTeamId: Number
});
And the proper model should be:
module.exports = mongoose.model('Match',{
id: Number,
region: String,
championsWin: Array,
championsLose: Array,
winner: Number
});
Thanks a lot for the help!

Related

Why does the Chrome devtool shows the object attributes and the object itself differently?

const a = {
age: 12,
name: 'Lucy'
};
console.log(a, a.age);
delete(a.age);
Can anyone explain to me what happens to the age property when I console.log it in Chrome dev tool and the result shows up like this?
Object {age: 12, name: "Lucy"} 12
name:"lucy"
__proto__:Object
And if I define another object and console.log it.
const b = {
age: 12,
name: 'lucy'
};
console.log(b);
The console prints all the property it has?
Object {age: 12, name: "lucy"}
age:12
name:"lucy"
__proto__:Object
that's because you console.log that object before you delete its property.
Object {age: 12, name: "Lucy"} is just a quick object snapshot done by Chrome devtool. It won't change whatever you did right after.
And when you expand to show object attributes, devtool link to object reference and shows current value.

Create a simple rank array using map function (JavaScript)

So essentially I have a JSON that it's in the format as so:
JSON= [
{username: foo, score: 12343},
{username: bar, score: 9432},
{username: foo-bar, score: 402, ...
]
I know that the JSON that I am getting back is already rank from highest to lowest, based on the scores.
How can I make an array that automatically inserts the rank position? For instance, I would like to see an output of :
[1, username: foo, score: 12343],
[2, username: bar, score: 9432],
[3, username: foo-bar, score: 402],...
Javascript got you covered already. An array always has indexes, though it starts at zero. If you want the best, just use
console.log(JSON[0]);
and if you insist on 1 being 1, try this
function getByRank(index) {
return JSON[index - 1];
}
so you will get the best with
console.log(getByRank(1)); // {username: "foo", score: 12343}
I think in your code the json is valid json, see the " around foo...
Your syntax seems off, but assuming that the JSON is:
JSON = [
{username: 'foo', score: 12343},
{username: 'bar', score: 9432},
{username: 'foo-bar', score: 402}
]
Since Arrays are 0 indexed and you have access to the current index in a .map method, you can do something along the following:
JSON = JSON.map(function (record, index) {
record.rank = index + 1;
return record;
})
This should give you the following output:
[
{ rank: 1, username: 'foo', score: 12343 },
{ rank: 2, username: 'bar', score: 9432},
{ rank: 3, username: 'foo-bar', score: 402}
]
Hope this helps.
Strictly from the point of view of your question, you already got the answer. I just want to enumerate some ideas, maybe they will be useful to some of you in the future:
First of all, JSON (JavaScript Object Notation) is an open-standard format that uses human-readable text to serialize objects, arrays, numbers, strings, booleans, and null. Its syntax, as the name states, is derived from JavaScript, but JSON is actually a text, a string.
A JSON string is (almost always) syntactically correct
JavaScript code.
Make sure you don't use the keyword "JSON" as the name of a variable, because JSON is actually an existing object in JavaScript, and it is used to encode to JSON format (stringify) and decode from JSON format (parse).
Just try JSON.stringify({a: 2, b: 3}); and JSON.parse('{"a":2,"b":3}'); in a JavaScript console.

cannot read property of undefined - but property exists

console.log(result.data[0]);
returns:
{ name: 'page_stories',
period: 'day',
values:
[ { value: 114, end_time: '2016-07-31T07:00:00+0000' },
{ value: 68, end_time: '2016-08-01T07:00:00+0000' },
{ value: 134, end_time: '2016-08-02T07:00:00+0000' } ],
title: 'Daily Page Stories',
description: 'Daily: The number of stories created about your Page. (Total Count)',
id: '462582393917692/insights/page_stories/day' }
but for some reason var name = result.data[0].name; is returning:
TypeError: Cannot read property 'name' of undefined
I can't for the life of me figure out why. the 'name' property clearly exists as does the result.data[0] object. Any help would be fantastic.
edit: found out that the data format wasn't uniform for every single request (just most!). Thanks for the responses. I should've made it clear that I was feeding batch requests through this code too.
Ensure that you are actually trying to access an object and not a string. JSON.parse(obj) if needed.

How to filter deeply stacked data inside an object(and edit\delete it afterwards)?

I have a problem here, and I can't find out how to solve it. I have an object with many levels. There is arrays with objects inside my object, and they have their arrays with objects too. Let me show you somekind of example here:
{
sections: [
{
currency_sections: [
{
positions: [
{
id: 131,
quantity: 24
},
{
id: 133,
quantity: 1
}
],
key: value,
key: value
},
{
positions: [
{
id: 136,
quantity: 2
},
{
id: 137,
quantity: 3
}
],
key: value,
key: value
}
],
key: value,
key: value
}
],
key: value,
key: value
}
I build my data via handlebars template. Which is not really important. But on my page I can change, let's say, quantity of the position. When I do that I have only id of the position I changed and new quantity.
So basically I need to filter my object to find one object in positions arrays that matches via id key and change quantity there.
Also I can delete whole position, and in that case I need to find position object with id needed and delete whole object.
The thing I can't understand is how I can filter all my data at once. And how can I manipulate unnamed object if I will find it.
And let's say I filtered it somehow. Can I return full path to that object for later use? In example - sections[0].currency_sections[1].positions[0] ? Because if I can do that than deleting and editing should be simple enough.
At this point I don't really have the time to redo everything on something more suitable like angular or ember. Although I have underscore and jquery.
Just wanted to update my question. At the end I just created a method that builds index of my elements.
function _createItemsIndex(data) {
if (!$.isEmptyObject(data)) {
$.each(data.sections, function (sectionIndex, section) {
$.each(section.currency_sections, function (curSecIndex, curSec) {
$.each(curSec.positions, function (positionIndex, position) {
_items.push({
id: position.id,
quantity: position.quantity,
price: parseFloat(position.price) || 0,
index: [sectionIndex, curSecIndex, positionIndex]
});
});
});
});
}
}
Thank you levi for your comments

iterating this response

{
'lastChangedName': null'Caption': 'Adhesive Tape',
'CreateByID': 0,
'DateOnSet': '02/10/2011',
'Note': 'Currently participating in Allergy shots to resolve this',
'Reaction': 'skin rash',
'SectionDescription': 'Allergy List',
'HistoryItemID': 1831,
'CurrentInDrFirst': 0,
'CreateDate': '/Date(1297674300000-0500)/',
'Code': '3746',
'PL': '1',
'Problem': {
"LastChargedByUserID": 0,
"LastChargedDate": null,
"ProblemStatus": 1003,
"DateResolved": "12\/2\/11",
"PatientID": 0,
"ProblemID": 1330
},
'CategoryDescription': null,
'CategoryID': 0,
'CodeSystem': 'FDBDRUG',
'SectionID': 3,
'LastChangedID': 0,
},
{
'lastChangedName': null'Caption': 'Cats',
'CreateByID': 0,
'DateOnSet': '6/4/1997',
'Note': '0',
'Reaction': 'Sneezing',
'SectionDescription': 'Allergy List',
'HistoryItemID': 1925,
'CurrentInDrFirst': 0,
'CreateDate': '/Date(1299176220000-0500)/',
'Code': '',
'PL': '1',
'Problem': {
"LastChargedByUserID": 0,
"LastChargedDate": null,
"ProblemStatus": 1002,
"DateResolved": null,
"PatientID": 0,
"ProblemID": 1331
},
'CategoryDescription': null,
'CategoryID': 0,
'CodeSystem': '',
'SectionID': 3,
'LastChangedID': 0,
}
This is the response i get, i want to iterate and print out the caption values... in a text box...
for each(var item in response) {
alert(item.caption)
}
This only prints me the first caption alone.
That response, as quoted, is awkward because you have a series of anonymous objects separated by commas (you might think it was invalid, but it's not, it's just unhelpful). (That's assuming you fix the 'lastChangedName': null'Caption' thing that symcbean pointed out in the comments; I assume that's a copy-and-paste error.) I think there must be more to it than what's quoted. (Is it, perhaps, inside [ and ], making it an array of objects?)
But generally speaking: Yes, for..in (not for each, just for) is used to loop through the names of the properties of an object, and once you have each name, you can use [] notation to retrieve the property value.
So if you can get a reference to each of those objects, you can use for..in to loop through the properties.
Example:
var obj, name;
obj = {
foo: "bar",
answer: 42
};
for (name in obj) {
console.log(name + ": " + obj[name]);
}
That will show
foo: bar
answer: 42
or
answer: 42
foo: bar
The order of the property names in the loop is not specified for generic objects like those in your example. (It's specified for Array objects: With Array objects it's guaranteed that any properties they have with purely numeric names — e.g., array indexes — will be iterated in numeric order. [Even then, if you have non-numeric properties on the array as well, it's undefined whether those will be before, after, or intermixed with, the numeric ones.])
Try:
for(var item in response) {
alert(response[item].caption)
}

Categories

Resources