Access prototype value from prototype function - javascript

How do I access open array that is prototyped from removeConnection() function? Right now I get ReferenceError: open is not defined when I call the function.
function Connections() {}
Connections.prototype.open = [];
Object.defineProperty(Connections.prototype, 'total', {
get: function total() {
return this.open.length;
}
});
Connections.prototype.removeConnection = function(res) {
this.open = open.filter(function(storedRes) {
if (storedRes !== res) {
return storedRes;
}
});
}
var connections = new Connections();

For me it raises a different error Uncaught TypeError: open.filter is not a function and the fix is to change this.open = open.filter to this.open = this.open.filter.
See the runnable example:
function Connections() {}
Connections.prototype.open = [];
Object.defineProperty(Connections.prototype, 'total', {
get: function total() {
return this.open.length;
}
});
Connections.prototype.removeConnection = function(res) {
this.open = this.open.filter(function(storedRes) {
if (storedRes !== res) {
return storedRes;
}
});
}
var connections = new Connections();
connections.open = ['one', 'two']
alert(connections.open)
connections.removeConnection('one')
alert(connections.open)

You're missing this.
Connections.prototype.removeConnection = function(res) {
this.open = this.open.filter(function(storedRes) {
if (storedRes !== res) {
return storedRes;
}
});
}

Related

Uncaught TypeError: Cannot read property 'open' of undefined

I created a function called Sensors and instantiated the serialport object within it. I also created a prototype find that in theory should access the port object to open, write and bind on.
I'm receiving error:
Uncaught TypeError: Cannot read property 'open' of undefined
I'm not sure why....
Code:
<script>
var sp = require('serialport');
var comports = [];
//Object to connect to a specific comport and send the 'i' command
function Sensors(com) {
this.find();
this.address = com;
this.port = new sp(com, {
baudrate: 9600,
autoOpen: false
});
}
Sensors.prototype.find = function() {
console.log("ran");
this.port.open(function(err) {
if (err) {
return console.log('Error opening port: ', err.message);
}
this.port.write('i' + String.fromCharCode(13), function(err) {
if (err) {
return console.log('Error on write: ', err.message);
}
console.log('message written');
});
this.port.on('data', function(data) {
var sensorData = data;
var splitString = sensorData.toString().split(',');
console.log(splitString[1]);
if (sensorData.length > 0) {
if (splitString[1] == 'pH' || splitString[1] == 'EC' || splitString[1] == 'RTD') {
console.log(splitString[1]);
}
this.port.close(function(err) {
console.log('port closed', err);
});
}
});
});
};
function findSensors() {
sp.list(function(err, ports) {
for (i = 0; i < ports.length; i++) {
var sensor = new Sensors(ports[i].comName);
sensor.find();
}
});
}
//startup function to find comports and find the sensor(s)
function startUp() {
findSensors();
}
</script>
In the constructor, you're calling this.find(); before you've assigned to this.port, so the line this.port.open inside find results in an error. Change it so that this.find runs after the port property has been populated.
function Sensors(com) {
this.address = com;
this.port = new sp(com, {
baudrate: 9600,
autoOpen: false
});
this.find();
}

Function is not recognized by another function in angularjs

During loading of the partial Html with controller, my function named $scope.actionViewVisitors() is recognized and runs without errors. But whenever I use it inside another function on the same controller, it gives me an error:
TypeError: $scope.actionViewVisitors is not a function. Please see my code below:
angular.module("Visitor.controller", [])
// ============== Controllers
.controller("viewVisitorController", function ($scope, $rootScope, $http, viewVisitorService, viewAccountService, DTOptionsBuilder) {
$scope.visitorList = null;
$scope.viewAccountDetail = null;
$scope.avatar = null;
$scope.visitorDetail = null;
$scope.visitorBtn = "Create";
$scope.actionViewAccount = function () {
$scope.actionViewAccount = viewAccountService.serviceViewAccount()
.then(function (response) {
$scope.viewAccountDetail = response.data.account;
$scope.avatar = "../../avatars/" + response.data.account.AccountId + ".jpg";
})
}
$scope.dtOptions = DTOptionsBuilder.newOptions()
.withDisplayLength(10)
.withOption('bLengthChange', false);
// THIS ONE IS NOT RECOGNIZED
$scope.actionViewVisitors = function () {
$scope.actionViewVisitors = viewVisitorService.serviceViewVisitors()
.then(function (response) {
debugger;
$scope.visitorList = response.data.visitorList;
});
}
// I DON'T GET ANY ERROR HERE
$scope.actionViewVisitors();
$scope.actionViewAccount();
$scope.createVisitor = function () {
$scope.statusMessage = null;
if ($scope.visitorBtn == "Create") {
$scope.createVisitor = viewVisitorService.serviceCreateVisitor($scope.visitorDetail)
.then(function (response) {
if (response.data.response == '1') {
bootbox.alert({
message: "Successfully created a new visitor.",
size: 'small',
classname: 'bb-alternate-modal'
});
} else if (response.data.response == '0') {
bootbox.alert({
message: "Failed in creting visitor.",
size: 'small',
classname: 'bb-alternate-modal'
});
}
});
debugger;
$scope.visitorDetail = undefined;
// I GET THE ERROR WHEN I CALL THIS METHOD
$scope.actionViewVisitors();
}
}
})
// ============== Factories
.factory("viewVisitorService", ["$http", function ($http) {
var fac = {};
fac.serviceViewVisitors = function () {
return $http({
url: '/Visitor/ViewVisitors',
method: 'get'
});
}
fac.serviceCreateVisitor = function(visitor) {
return $http({
url: '/Visitor/CreateVisitor',
data: { visitor: visitor },
method: 'post'
});
}
return fac;
}])
You are overwriting the function with Promise in the following line, thus the error is correct
$scope.actionViewVisitors = function () {
$scope.actionViewVisitors = viewVisitorService.serviceViewVisitors()
.then(function (response) {
$scope.visitorList = response.data.visitorList;
});
}
Remove $scope.actionViewVisitors =
$scope.actionViewVisitors = function () {
viewVisitorService.serviceViewVisitors()
.then(function (response) {
$scope.visitorList = response.data.visitorList;
});
}
On the first call to the function you are changing it from a function to a Promise. Maybe you want to be returning the result instead?
$scope.actionViewVisitors = function () {
return viewVisitorService.serviceViewVisitors()
.then(function (response) {
debugger;
$scope.visitorList = response.data.visitorList;
});
}

Sending array data from server to client in Meteor

So I'm trying to send my data from my server code to my client code, yet it's returning undefined. Not sure what to do as I've been stuck here for a while.
I used these packages:
https://github.com/meteorhacks/npm
https://www.npmjs.com/package/wiki-infobox
Rappers = new Mongo.Collection(null)
var page = 'Tupac'
var language = 'en'
var rappers = null
var texts
var rappers2
if (Meteor.isClient) {
getGists = function getGists(user, callback) {
Meteor.call('getGists', user, callback);
}
Meteor.startup(function() {
rappers2 = []
function call(text, callback) {
Meteor.call('getWikiStuff', rappers2, function(err, result) {
console.log(result)
})
var timer = setTimeout(function() {
callback()
}, 4000)
}
function consoleit() {
console.log(rappers2)
}
call('hello', consoleit)
})
}
if (Meteor.isServer) {
Meteor.startup(function() {
Meteor.methods({
getWikiStuff: function(rappers3) {
var infobox = Meteor.npmRequire('wiki-infobox')
var bound = Meteor.bindEnvironment(function(callback) {
callback()
});
console.log("HERE")
bound(function() {
infobox(page, language, function(err, data) {
if (err) {
return
}
rappers = data.associated_acts
for (var x = 0; x < rappers.length; x++)
if (rappers[x].text != undefined) {
var yo = rappers[x].text
rappers3.push(yo)
}
for (var value of rappers3)
console.log(value)
})
})
return rappers3
}
})
})
}

nodeStack.getFunctionName() returns null

I have the following node.js code:
var path = require('path');
var nodeStack = require('stack-trace');
var controller = (function () {
function controller() {
}
controller.prototype.render = function (res, model, view) {
var stack = nodeStack.get();
var frame = stack[1];
var functionName = frame.getFunctionName().split(/controller\./i);
if (functionName.length < 2) {
functionName = frame.getFunctionName().split(/(controller|\./i);
}
if (!view) {
view = functionName[1];
var dotidx = view.indexOf('.');
if (dotidx > -1) {
view = view.substring(0, dotidx);
}
}
if (!model) {
model = {};
}
var base = '';
if (res.locals.basePath) {
base = res.locals.basePath;
}
var cls = functionName[0];
res.render(path.join(base, cls, view), model);
};
return controller;
})();
module.exports = controller;
The code should allow me to render a view based on the method, the matching file should be found automatically.
It works all fine, just in one case frame.getFunctionName() returns null.
The code for the subclasses look as follows:
customerController.prototype.add = function (req, res) {
var _this = this;
somepromise.then(function (provider) {
return provider.getCP();
}).then(function (cp) {
controller.prototype.render.call(_this, res, { title: 'add customer', contactpersons: cp });
}, function (err) {
controller.prototype.render.call(_this, res, { title: 'add customer' });
});
};
The one code that doesn't work.
customerController.prototype.details = function (req, res) {
var _this = this;
somepromise.then(function (provider) {
return provider.getCustomerById(req.param('id'));
}).then(function (customer) {
_super.prototype.render.call(_this, res, { title: 'customer details', customer: customer });
}, function (err) {
res.status(404).send(err);
});
};
The code works for all methods except one. Do you have an idea why?
Remarks: The code is compiled from TypeScript

How can I get sinon to yield to multiple callbacks

I am trying to stub several ajax calls, but I want to have both beforeSend and success executed, is this possible?
I want something like this:
var stub = sinon.stub(jQuery, "ajax");
stub.onCall(0).yieldsTo("beforeSend").yieldsTo("success", {some: 'data'});
stub.onCall(1).yieldsTo("beforeSend").yieldsTo("success", {other: 'stuff'});
But this skips the 'beforeSend' method.
I know it would be easier to allow ajax to do it's stuff and use sinon's fakeServer, but I can't as I'm testing in Node with a fake browser and it just doesn't work
You could use yieldTo after the call:
var stub = sinon.stub();
stub({
foo: function() {
console.log('foo');
},
bar: function() {
console.log('bar');
}
});
stub.yieldTo('foo');
stub.yieldTo('bar');
I was able to work around this by adding some additional code:
var responses = {};
var executionComplete;
beforeEach(function () {
executionComplete = $.Deferred();
sinon.stub($, "ajax", function (options) {
if (options.beforeSend) {
options.beforeSend();
}
completeAjaxCall(options);
});
});
afterEach(function () {
$.ajax.restore();
});
var completeAjaxCall = function (options) {
var response = findResponse(options.url, options.type);
setTimeout(function () {
if (response.code < 400) {
if (options.dataFilter && response.data) {
response.data = options.dataFilter(JSON.stringify(response.data));
}
if (options.success) {
options.success(response.data);
}
} else {
if (options.error) {
options.error(response.data);
}
}
if (options.complete) {
options.complete();
}
if (response.completeExecution) {
executionComplete.resolve();
}
}, response.serverResponseTime);
};
var findResponse = function (url, type) {
var response = responses[url];
expect(response, url + ' should have a response').to.exist;
expect(response.type).to.equal(type);
delete responses[url];
if (Object.keys(responses).length === 0) {
response.completeExecution = true;
}
return response;
};
var givenResponse = function (response) {
responses[response.url] = response;
};
Then in my test I can use it like this:
it('should do some stuff', function (done) {
//given
givenResponse({serverResponseTime: 4, code: 200, url: '/saveStuff', type: 'POST'});
givenResponse({serverResponseTime: 1, code: 200, url: '/getStuff', type: 'GET'});
//when
$('button').click();
//then
executionComplete.then(function () {
expect(something).to.be.true;
done();
});
});

Categories