when i test ?_escaped_fragment_= , i get
TypeError: 'undefined' is not a function (evaluating 'document.querySelectorAll.bind(document)')
http://localhost:3000/packages/material-design.js?e252ae03c7066a6ce33a348a22662a73cee8811e:75
http://localhost:3000/packages/material-design.js?e252ae03c7066a6ce33a348a22662a73cee8811e:315
http://localhost:3000/packages/material-design.js?e252ae03c7066a6ce33a348a22662a73cee8811e:318
http://localhost:3000/packages/material-design.js?e252ae03c7066a6ce33a348a22662a73cee8811e:778
The html in the body does show up but I do not get any meta tags and there is a huge blank space in the head before the title.
i followed http://www.meteorpedia.com/read/spiderable/ and ran phantomjs phantomtest.js
❯ phantomjs phantomtest.js [17:50:01]
Loading page...
Page load status: success
not ready, Meteor undefined
i got this.
Any idea what's wrong? Thanks.
In phantomjs, which is used by spiderable, the bind method is not supported. If you're the owner of material-design I would suggest replacing bind with _.bind. Otherwise, you can add a polyfill to your project to make sure that Function.prototype.bind is properly defined.
EDIT
To make sure your browser supports bind put this code somewhere in your code base:
if (!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function() {},
fBound = function() {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
The above implementation is copy/pasted from here.
Related
This question seems to be more or less a duplicate of this one, but that one received no answers and is over 2 years old so I don't know what the protocol is (I tried to find out).
Anyway, I've written an ASP.NET MVC5 web app and it all works fine in debug. After publishing to the server with the Release configuration I started seeing the error "Uncaught ReferenceError: Cannot access 'n' before initialization".
After many hours of trawling through the code I think I've isolated the issue. I have this small function (it's a Knockout view model, but that's irrelevant):
eventIndexViewModel = function (params) {
let self = this;
// Map values from params object to properties of self
for (const [key, value] of Object.entries(params)) {
self['_' + key] = value;
}
self.eventsView = ko.observable(self._eventsView);
self.calendarToggleButtonClass = ko.pureComputed(function () {
return self.eventsView() === "calendar" ? "active" : "";
});
self.tableToggleButtonClass = ko.pureComputed(function () {
return self.eventsView() === "table" ? "active" : "";
});
};
After being minified and published to the server, if I view the source in the dev tools console it looks like this:
eventIndexViewModel = function(n) {
let t = this;
for (const [n,i] of Object.entries(n))
t["_" + n] = i;
t.eventsView = ko.observable(t._eventsView);
t.calendarToggleButtonClass = ko.pureComputed(function() {
return t.eventsView() === "calendar" ? "active" : ""
});
t.tableToggleButtonClass = ko.pureComputed(function() {
return t.eventsView() === "table" ? "active" : ""
})
}
It is overkill to map the properties for the params object in this way in this particular instance, but I have much larger view models with many more properties in the same project and I want to keep them code consistent, so go with it.
Unless I'm misunderstanding something, the minified version has renamed both the params variable and the key variable in the for statement to n, and I think that is what is causing my error. Certainly, that line with the for statement is where the error is thrown.
Am I understanding the cause of this problem correctly? If so, is it a bug in the minification process? And either way, how can I get around it?
I am hoping someone will be able to help me out with a small issue. I am trying to stub out an undefined property that lives inside a function and return a known value, I am trying this with a simple test case:
var self = this;
self.test = function() {
return person.myId();
};
if (typeof module !== "undefined" && module.hasOwnProperty("exports")) {
module.exports = self;
}
return self;
what I have tried to do is:
it('Basic stub test', function() {
sinon.stub(code, 'person.myId').return("1234");
assert(code.test(), "1234");
});
I had hoped the above would stub any calls made to person.myId(), however, I just get any error saying: Cannot stub non-existent own property person.myId.
We use our own software that handles dependency injection (e.g. during runtime in our software person is made available) but we are attempting to write isolated unit tests outside of the software, hence the necessity for stubbing out the missing dependencies.
Has anyone attempted this kind of thing before? Am I trying to do something that isn't possible?
Thank you for any help/support anyone can provide.
Sam
I'm not sure what kind of magic the dependency injection software does, so here is a middle ground answer.
It's less than ideal because it tends to be a code smell if you're changing the code you want to test, although it fits your specific question.
I'm also assuming you're using something like mocha that provides the before & afterEach functions.
var sandbox = sinon.createSandbox();
before(function () {
var person = {
myId: () => console.log('myId no op'),
};
code.person = person;
}
it('Basic stub test', function() {
sandbox.stub(code.person, 'myId').returns('1234');
assert(code.test(), '1234');
});
afterEach(function () {
sandbox.restore();
});
Documentation Link: http://sinonjs.org/releases/v4.1.3/sandbox/
(Although the use of sandbox isn't strictly required here)
I am using Meteor 1.4.
Template.showProducts.onCreated(() => {
var handle = Meteor.subscribe("products");
//not working: var handle = this.subscribe("products");
//not working: var handle = Template.instance().subscribe("products");
Tracker.autorun(() => {
//not working: this.autorun
const isReady = Meteor.ready();
//not working: this.subscriptionsReady()
if(isReady){
const products = Products.find().fetch();
Session.set("prods", products);
}
});
});
If I use "this.subscribe", I got:
Uncaught TypeError: _this.subscribe is not a function
If I use "Template.instance()", I got:
Cannot read property 'subscriptionsReady' of null
If you use an arrow function, then the value of this which Meteor tries to pass in is lost. Instead use a regular anonymous function (function () { ... }).
You should then use this.autorun rather than Tracker.autorun. This will ensure that the autorun is cleaned up when the template disappears, and will allow Template.instance to work inside the autorun.
The problem is that you're passing the onCreated handler an arrow function, which does not allow binding of this (reference). As a result, Meteor is unable to correctly bind the template instance it has just created, and your subscriptions (and various other things) will fail.
The fix is just to pass onCreated a traditional JS function:
Template.showProducts.onCreated(function () {
...
i am stuck with this for few days now.
I have route with resolve, which looks something like this:
.when('/list/',{
controller : 'list',
templateUrl : 'template/list.stache',
resolve : {
list : function($q,$firebase){
var d = $q.defer(),
ref = new Firebase(_config.url+'/list/');
ref.once('value', function(s){
if(s.val() == null){
d.reject('Object not found');
}
d.resolve($firebase(ref));
});
return d.promise;
}
}
})
It works great in any browser, for some reason it fails in Android app ( using phonegap ), it loads data correctly, but when you try to save it ( using $save() ), data updates locally but fails to do so remotely.
Tested few theories, tried to call $firebase within controller, using something like:
$scope.fb = $firebase(new Firebase(_config.url+'/list/'))
$scope.fb.$on('loaded', function(d){
$scope.fb[$scope.fb.$getIndex()[0]].test = 'AAAAAA!'
$scope.fb.$save()
})
The above worked as should, so i assume it has something to do with promises.
Would anyone have any ideas?
EDIT ---
Still struggling to figure out the issue, but was able to narrow it down to resolve:
.when('/list/',{
controller : function(){
new Firebase('https://XXX.firebaseio.com/test/').push('Hey!');
},
templateUrl : 'template/list.stache',
resolve : {
list : function($q,$firebase){
var d = $q.defer(),
ref = new Firebase(_config.url+'/list/');
ref.once('value', function(s){
if(s.val() == null){
d.reject('Object not found');
}
d.resolve($firebase(ref));
});
return d.promise;
}
}
})
It fails. But :
.when('/list/',{
controller : function(){
new Firebase('https://XXX.firebaseio.com/test/').push('Hey!');
},
templateUrl : 'template/list.stache'
})
Works as expected.
Note that both approaches works fine in a browser ( tested on firefox and chrome ). It only fails when compiled to android app using phonegap.
Any ideas are appreciated.
I had the same thing. The connection is lost.
Use the function Firebase.goOffline(); and Firebase.goOnline();. This allows you to manually control the client connection.
Example:
var usersRef = new Firebase('https://samplechat.firebaseio-demo.com/users');
Firebase.goOffline(); // All Firebase instances are disconnected
Firebase.goOnline(); // All Firebase instances automatically reconnect
Link for reference
This is for a phonegap angular app. I would have thought binding to the db query return, result.rows in my case would be possible but it seems like it is not. The only way I could get this to work was with the commented out code where I manually push the data into an array row by row. Is this the only way?
The actually error received by binding to .rows is: Error: Duplicates in a repeater are not allowed. Repeater: item in items key: undefined:undefined
The service:
// only portion of code shown
query: function (q) {
var d = $q.defer();
var db = this.getDb();
db.transaction(function (t) {
t.executeSql(q, [], function (tx, results) {
d.resolve(results);
}, function (err) {
d.reject(err);
});
}, function (err) {
d.reject(err);
}
);
return d.promise;
}
The controller is like this:
Sql.query('select * from DEMO').then(function (data) {
console.log(data);
//$scope.items = [];
//for (i = 0, l = data.rows.length; i < l; i++) {
//$scope.items.push(data.rows.item(i));
//}
$scope.items = data.rows; // this errors out
$scope.$safeApply();
});
The repeater is just a simple:
<div ng-repeat='item in items'>{{item.id}} {{item.data}}</div>
Based on the error message it looks like you have more than one undefined item in the data.rows array.
Your working code uses data.rows.item(i) is that creating an new empty object instead of undefined? Try changing data.rows.item(i) to data.rows[i] in your working code does that break as well?
Assuming you are using angular 1.1.5 here are some options:
Use your current workaround
Downgrade to 1.1.4 or to the current stable 1.0.7. I think 1.1.4 will work based on a broken version with 1.1.5 and a working version with 1.1.4.
Remove any duplicate undefined rows from data.rows
Note: For others having a similar type of error Angular generates a $$hashKey to objects when doing an ng-repeat. This error indicates the same object is in the array (with the same $$hashKey) and is not allowed in 1.1.5 (and later?).
See this blog post and google groups post for more info. Also this pull request looks related so I'm not sure if this behavior is intended going forward though it appears to have been fixed in the past.