Getting uncaught error in ember - javascript

When I'm doing the right click option for more than 5 (approx) times for certain task, it showing uncaught error as like below:
Uncaught TypeError: Cannot read property 'find' of undefined
at Class.<anonymous> (core.js:21487)
at fn (core.js:7779)
at DeferredActionQueues.flush (core.js:7723)
at Backburner.end (core.js:7738)
at Backburner.run (core.js:7748)
at executeTimers (core.js:7824)
at core.js:7822
In that Place I'm having the below code:
Ember.run.later(view, function () {
this.$().find('menu-item:eq(0)').focus();
}, 125);
Can anyone please suggest me why this error is coming and I need to avoid this error while right clicking the task for "n" number of time also. I'm new to the ember. Your help will be appreciate. Thanks in advance.

Thats a simple javascript issue. In the second line this.$() returns undefined, and so it can't call .find on undefined.
More interesting is why this.$() is undefined. Probably you have this code inside a component, and try to access the local jQuery instance. However you call it inside an anonymous function(){}, which breaks your this-context (because it gets a new one).
The best solution here is to use an arrow function:
Ember.run.later(view, () => {
this.$().find('menu-item:eq(0)').focus();
}, 125);
this prevents the outer this context, which is nice. Another options is to save this:
const self = this;
Ember.run.later(view, function () {
self.$().find('menu-item:eq(0)').focus();
}, 125);
Or you can .bind(this):
Ember.run.later(view, (function () {
this.$().find('menu-item:eq(0)').focus();
}).bind(this), 125);
I can definitely recommend the first option, especially when using ember(-cli) which gives you transpilation anyway.

Related

Can't access "this" from only one method

I'm just missing something (which is terrible considering the kind of thing I'm missing) about "this". I have a class for log formatting. In only one method, which is intended only for debugging/testing, "this" turns out to be undefined. I removed almost everything for demonstration purposes only. The code goes as following:
class LogFormatter {
constructor(source) {
// nothing relevant.
}
formatted() {
return 'returns a formatted string whatever';
}
clog(message, sub) {
console.log(this.formatted());
}
// made only for testing
showThis() {
console.log(this);
}
}
And it is used like this:
const
LogFormatter = require('log-formatter'),
lgf = new LogFormatter('asd');
lgf.clog('whatever');
If I access this from formatted method, or even by calling showThis, it works just fine. So it does not seems to be something related to console.log.
When I call clog method, the next error is thrown:
console.log(this.formatted());
^
TypeError: Cannot read property 'formatted' of undefined
So, only in clog method, "this" is undefined. So what's the elephant in front of my that I'm not seeing? :)
EDIT: Note that if I add a console.log(this) inside the formatted method, works fine too.
Also, I've noticed that if I -try to- create a new object from LogFormatter this way:
const
LogFormatter = new require('log-formatter')('whatever')
Throws an exception, saying that I cant execute LogFormatter without new keyword, which AFAIK, should work, given the fact that the class is the only thing being exported via module.exports = LogFormatter. Also, I did not have this problem using good old constructor functions syntax.
Thanks in advance :)

Javascript - pass THIS in function doesnt work

I am very new to Javascript and I just stuck with something that works in python.
The problem is that I have class where I initiate some empty lists as this.data_y_json and etc. If I make normal function inside class like normal_function(){this.data_y_json = 5} it works and the variable is changed.
However, i work with d3, and there is some trick which I cant get through:
// inside class
// in constructor all this.xxx defined
// after object initiation I call set_data()
set_data(){
d3.json("link2.json",function(data) {
for (var i=0;i<data.d.results.length;i++){
this.data_y_json.push(parseFloat(data.d.results[i].PE))
...
//end of function
// end of class
After calling function set_data() an error is raised: SCRIPT5007: Unable to get property 'data_y_json' of undefined or null reference
I am rewriting my visualization into OOP, before this, I had it solved with global variables and it worked fined. In python I would just passed 'self' as an argument to function, but here in javascript, passing THIS doesnt work and raises another error.
Simply said, I know the problem -> this.data_y_json is not recognized propably because of function(data) doesnt pass self of the object, but I dont know how to do it.
Thank in advance for advice
Are you in an ES2015 environment? Changing your callback to be an arrow function should scope this to be what you want
d3.json("link2.json", (data) => {
for (var i=0;i<data.d.results.length;i++){
this.data_y_json.push(parseFloat(data.d.results[i].PE))
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
For reading up on the arrow function and the scoping of this

Javascript - Error when calling "apply" on cloned native function

I'm trying to clone the function indexedDB.cmp in Chrome, then replace indexedDB.cmp with a new function. The new function logs the passed arguments using console.log, then calls the cloned function using apply. However, I keep getting the error "Illegal Invocation" when I use apply. I only need this to work on Google Chrome. Any help would be appreciated!
function init() {
var i = indexedDB;
i.cmp2 = i.cmp.bind({});
i.cmp = function(...a) {
console.log("CMP call!",a);
return i.cmp2.apply(null,a);
};
}
init();
indexedDB.cmp("/testFolder",3);
"Since you're already using spread syntax, why not invoke the function with spread instead of apply? – Mikael Lennholm"
I also changed i.cmp.bind({}) to i.cmp.bind(i).

Change element on page init of jquery mobile

I try to change slider properties on page init :
$(document).delegate('#my-page','pageinit', InitMyPage());
function InitMyPage() {
var today = new Date();
$("#my-slider").prop({
min: 1,
max: 50
}).slider("refresh");
}
It looks like on the page init $("#my-slider") still unknown.
When I try to get it on console at this point its look like this:
$("#year-slider")
[]
And I get error:
Uncaught TypeError: undefined is not a function
When can I change the elements (which event)?
This code:
$(document).delegate('#my-page','pageinit', InitMyPage());
calls InitMyPage and passes its return value into delegate, exactly the way foo(bar()) calls bar and passes its return value into foo.
To pass the function into delegate instead, remove the () from after it:
$(document).delegate('#my-page','pageinit', InitMyPage);
// No () here ----------------------------------------^
And I get error:
Uncaught TypeError: undefined is not a function
When can I change the elements (which event)?
That's because InitMyPage doesn't return anything, so the result of calling it is undefined, which is being passed into delegate. Later when the event occurs, apparently jQuery Mobile tries to call that undefined (which, not being a function, causes the error). I'm slightly surprised jQuery Mobile doesn't notice that and not try to call it, but... :-) Fixing the other thing will fix this.

Objects in JavaScript defined and undefined at the same time (in a FireFox extension)

I am chasing down a bug in a FireFox extension. I've finally managed to see it for myself (I've only had reports before) and I can't understand how what I saw is possible.
One error message from my extension in the Error Console is "gBrowser is not defined". This by itself would be surprising enough, since the overlay is over browser.xul and navigator.xul, and I expect gBrowser to be available from both. Even worse is the actual place where it happens: line 101 of nextplease.js. That is, inside the function isTopLevelDocument, which is only called from onContentLoaded, which is only called from onLoad here:
gBrowser.addEventListener(this.loadType, function (event) {
nextplease.loadListener.onContentLoaded(event);
},
true);
So gBrowser is defined in onLoad, but somehow undefined in isTopLevelDocument.
When I tried to actually use the extension, I got another error: "nextplease is not defined". The interesting thing is that it happened on lines 853 and 857. That is, inside the functions
nextplease.getNextLink = function () {
nextplease.getLink(window.content, nextplease.NextPhrasesMap, nextplease.NextImagesMap, nextplease.isNextRegExp, nextplease.NEXT_SEARCH_TYPE);
}
nextplease.getPrevLink = function () {
nextplease.getLink(window.content, nextplease.PrevPhrasesMap, nextplease.PrevImagesMap, nextplease.isPrevRegExp, nextplease.PREV_SEARCH_TYPE);
}
So nextplease is somehow defined enough to call these functions, but isn't defined inside them.
Finally, executing typeof(nextplease) in Execute JS returns "object". Same for gBrowser.
How can this happen? Any ideas?
For the second case:
nextplease.getNextLink = function () {
nextplease.getLink(window.content, nextplease.NextPhrasesMap, nextplease.NextImagesMap, nextplease.isNextRegExp, nextplease.NEXT_SEARCH_TYPE);
}
nextplease.getPrevLink = function () {
nextplease.getLink(window.content, nextplease.PrevPhrasesMap, nextplease.PrevImagesMap, nextplease.isPrevRegExp, nextplease.PREV_SEARCH_TYPE);
}
I'd try this instead:
nextplease.getNextLink = function () {
this.getLink(window.content, this.NextPhrasesMap, this.NextImagesMap, this.isNextRegExp, this.NEXT_SEARCH_TYPE);
}
nextplease.getPrevLink = function () {
this.getLink(window.content, this.PrevPhrasesMap, this.PrevImagesMap, this.isPrevRegExp, this.PREV_SEARCH_TYPE);
}
I'm not sure what's happening (in which context the code is running and therefore why it's not seeing the gbrowser and other global variables) but an easy workaround for gbrowser being undefined would be to get a reference to the main window and access it from there:
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindow);
mainWindow.gbrowser.addEventListener( ... )
This should work independently of the context where the code is running since you would not rely on global variables.

Categories