can't access array of objects in object - javascript

I'm baffled about why I'm getting an error when trying to access an array inside of an object in ReactJS.
I am using Redux to store an object in State.
I have a success function that allows the page to render, so by the time I get to this object it has for sure loaded. (I noticed a ton of similar questions to this where that's usually the problem).
When I do this I get the proper results:
const { events } = this.props
console.log(JSON.stringify(events.listSignup))
{"data":[{"eventID":"264712106049274377","name":"BookOne","email":null,"verify":null,"privacy":null,"order":null,"group":null},{"eventID":"264712106049274377","name":"BookTwo","email":null,"verify":null,"privacy":null,"order":null,"group":null}]}
I can see that the array "data" exists, but when I try:
console.log(JSON.stringify(events.listSignup.data[0].name))
or
console.log(JSON.stringify(events.listSignup.data[0]))
I get "TypeError: Cannot read property 'data' of undefined"
I'm at my wits end trying to figure out what's going on. Any advice would be much appreciated!

You're right to be baffled, because what you [think you] have observed isn't possible.
This happens a lot to me as a developer, and my advice is that when this happens, trust your knowledge (you know this isn't possible!) and double check what you are seeing.
I suspect that the first time your component renders, this.props.events is undefined, but then it very quickly re-renders with this.props.events being set.
I would suggest adding back this line (without the others):
console.log(JSON.stringify(events.listSignup))
And scrolling up in your javascript console to see if you have any logs that are just displaying undefined. If so, you probably need to double check the logic which is preventing the page from rendering before you have successfully received the data, as I suspect that is where your problem is.

Related

Make properties lazy

I was reading the article on best practices here. And i came across the following lines:
A developer might attempt to set a property on your element before its definition has been loaded. This is especially true if the developer is using a framework which handles loading components, inserting them into to the page, and binding their properties to a model.
And the proposed solution to solve this problem was:
_upgradeProperty(prop) {
if (this.hasOwnProperty(prop)) {
let value = this[prop];
delete this[prop];
this[prop] = value;
}
}
I have been trying the understand the scenario in which this would happens, and try to understand how this fragment of code solves this problem. I have trying to find any reference material around but wasnt able to find anything similar like this.
Please could someone explain this scenario and what problem are we trying to solve here.
Web Components doesn't fully initialize your element until you call customElements.define('custom-tag', CustomElement); however, any <custom-tag> exists in the DOM as an HTMLUnknownElement as soon as the page renders. So in the period of time between when the page renders and when you call customElements.define(...), it's possible for someone to call something like:
document.querySelector('custom-tag').someProperty = someValue
which would modify the property of the not-yet initialized CustomElement.
Why would this happen?
I think this would most likely come up as a side-effect of using Web Components with a frontend framework (Angular, Vue, etc). These frameworks often have initialization code that happens after render, and there may be situations where a user may not have sufficient control to prevent the framework from initializing before Web Components.
How does the code fragment solve the problem?
The fragment function, _upgradeProperty() is meant to be called within the connectedCallback(), which is called after the Web Component has been fully defined and attached to an existing element. If you have any custom setter in your class, like:
class CustomElement {
set someProperty(value) {
this._someProperty = value.toLowerCase();
}
}
Then it's possible the property was set before the setter existed, meaning the raw value was saved directly to the instance's someProperty property, instead of being converted to lowercase and saved to _someProperty. Deleting the property and reassigning it after the setter has been defined ensures that the value is properly processed (in this case, made lowercase and saved in the right location).

Vue Material - MdTable initialization error in data fetching

As I stated here, I'm trying to fetching remote data to initialize MdTable component, but the process throws a null error. Data being fetched from a MySQL DB, part of a Laravel 5.6 API project.
After a deep analysis, I assumed that the issue is caused by a premature initialization of component itself, before the finish of fetching process. So, the model that manage component data results empty, and rendering crashes.
I tried different ways: the navigation is managed by Vue-Router, so both Before/After Navigation data fetching techniques has been tested, and the result is the same. Using props from parent component, as well as defining component navigation guards, seems to be useless in order to avoid the problem.
I think the solution could be to hold the component rendering until data being fetched. But I really don't get how. I tried with beforeCreate()/created() too, but none of them helped.
I'm stuck from many days in this situation, some help or suggestion to try at last a new direction is really appreciated.
Thanks in advance for help.
As I stated here, Due to a syntax error on my implementation:
[...]
<md-table-cell v-for="(val, i) in item" :key="val.id" v-if="(i !== 'id') && (i !==
'estensione_garanzia') && (i !== 'note')"
[...]
The attribute :key="val.id" is misconfigured. In this case I'm iterating an array of objects - without nested of them - so there's no sub-property id on selected element. For more information the official doc shows a complete example
By changing the attribute like this:
:key="val.id"
Everything works fine.

Erratic behavior of Javascript - Cannot read property 'longitude' of undefined

I'm working on an Angular App, which loads data from an API.
Everything is working as expected, except periodic receiving this bug in Chrome console.log
TypeError: Cannot read property 'longitude' of undefined
This causes some of the subsequent functions to disfunction aswell. The line angular complains at, is the following
function updateMapWaypoint(lastposition) {
console.log("updateMapWaypoint(%s) called", lastposition);
console.log($scope.units[$scope.selectedUnitIndex]);
var longitude = (lastposition) ? $scope.units[$scope.selectedUnitIndex].lastposition.gps.longitude : $scope.unsortedPositions[$scope.selectedPositionIndex].gps.longitude;
Where to two first is debugging and the last one, the line causing trouble. As far as I can see from the printet object in the console. Javascript should have no trouble locating longitude from the object, however it throws the error and I can't find any way to solve it.
All help is appreciated and if more details is required, I'll provide if possible for me.
This looks like it might be a race condition.
console.log() will show you the object as it is right now, and not what is was when you called console.log(). To see the properties of an object at a certian point in time you must copy its content and send them to console.log(), for example by stringifying it:
console.log(JSON.stringify(myObject))
Or if you are using Angular:
console.log(angular.extend({}, myObject));
This is confusing (it has messed with me several times). Remember that you are sending console.log() an object reference, not a copy of the object.

Meteor helper functions versus variables?

I was trying to display a count of all online users on my website, and installed the meteor-user-status plugin to help with this. I thought all I had to do was add a template helper
Template.header.helpers({
numOnline: Meteor.users.find({"status.online":true}).count()
});
like so, and include the {{numOnline}} variable in my header template. But, for some reason, that resulted in always displaying 0 users online. However, when I simply ran the method Meteor.users.find({"status.online":true}).count() in the javascript console, it gave the correct amount of users online.
After messing around with it a bit, I got it to work by wrapping it in a function:
Template.header.helpers({
numOnline: function(){
return Meteor.users.find({"status.online":true}).count();
}
});
This change makes it work perfectly, but I have no clue why. Can someone explain why it was necessary to wrap it in a function?
Adding Christian Fritz, The only reason I think this can be happening is in the first case numOnline: Meteor.users.find({"status.online":true}).count() the collection is not ready at the point of evaluation of the template and assign 0 or empty array [] since is what the subscription return, and in the second case since is a function will react whenever a change occurs in a collection, so that's why will have the value a soon the collection get fill with the subscription and the function will get execute whit the most recent value.Just my two cents. Please correct me if I'm wrong.
Well, that's just what it is (and the documentation tells you so, too). The reason why this need to be a function is reactivity: in order to reevaluate the piece of code at a later point in time (when a reactive datasource has changed value), you need to have a function.

Accessing javascript property yields different result when being accessed directly than when reading object in dev tools

I'm trying to debug the popular "cannot call method 'addClass' of undefined" of jQuery slider in range mode, and finding some strange things. Some people say this error is due to values being passed in as strings instead of integers, but my values are verified integers and I'm out of ideas, so I went to try and debug jQuery UI, hitting a dead end instantly.
See image:
As you can see, when I expand the options object in the dev tools, options.values is an array of two NaNs. However, if I console.log(options.values) I get the real array, as it should be, with proper numeric values. What's worse, when I log them directly with console.log(options.values[0]) for example, I get the proper value.
However, when slider requests the values, it always gets NaN back - this is apparent when calculating the closestHandle for the range slider - the NaN is so toxic it poisons the entire loop and returns an undefined closestHandle, thus causing the aforementioned "addClass" error.
Why does the situation from the image happen? Why can it happen? Apparently two identical properties contain different values depending on the way of accessing them.
The Chrome console is a bit tricky. The state of the Object you see in does not necessarily reflect the state at the time it was logged. It can be an 'updated' view.
While this does not solve your main problem it's obvious that logging an object doesn't help you much with debugging on Chrome in many situations. A breakpoint would be a better choice.
That said, somewhere in your code the object seems to be changed.

Categories