scratching my head over "this" statement in javascript. anyone help please - javascript

Ok after a day I managed to narrow down the problem to 2 lines of code. Maybe I am trying to use the this statement incorrectly.
function scheduleItemView(myId){
this.update = function(show){
document.getElementById(this.id+'-title').innerHTML = show.title +": "+ show.startDate;
document.getElementById(this.id+'-title-overlay').innerHTML = show.title +": "+ show.startDate;
document.getElementById(this.id+'-description').innerHTML = truncate(show.description,190);
document.getElementById(this.id+'-time-start').innerHTML = show.startTime;
document.getElementById(this.id+'-time-end').innerHTML = show.endTime;
};
this.id=myId;
return true;
}
function nowNextView(){
this.now = new scheduleItemView('now');
this.next = new scheduleItemView('next');
this.update = function(type,args){
var myshow=args[0];
// problem is below. I have to use the global name to access the update method.
myNowNextView.now.update(myshow.now);
myNowNextView.next.update(myshow.next);
// whereas what I want to do is reference them using the "this" command like below.
// this.now.update(myshow.now);
// this.next.update(myshow.next);
// the above doesnt work. The update method in scheduleItemView is not seen unless referenced globally
// BUT even more infuriating, this.now.id does return "now" so it can access the object, just not the method
// any ideas?
};
}
object is then instantiated with
var myNowNextView = new nowNextView();
and then I run the method:
myNowNextView.update(stuff);
I tried to describe the problem within the body of the program. No error in the code was thrown, and I had to do a try/catch before it grudgingly told me that it couldn't find the method.
Is the design flawed somehow? can I not do this?
Many thanks in advance,
Steve

function scheduleItemView(myId){
this.update = function(show){
document.getElementById(this.id+'-title').innerHTML = show.title +": "+ show.startDate;
document.getElementById(this.id+'-title-overlay').innerHTML = show.title +": "+ show.startDate;
document.getElementById(this.id+'-description').innerHTML = truncate(show.description,190);
document.getElementById(this.id+'-time-start').innerHTML = show.startTime;
document.getElementById(this.id+'-time-end').innerHTML = show.endTime;
};
this.id=myId;
}
function nowNextView(){
var myshow=args[0];
var scope = this;
this.now = new scheduleItemView('now');
this.next = new scheduleItemView('next');
this.update = function(type,args){
scope.now.update(myshow.now);
scope.next.update(myshow.next);
};
}

I think you could really benefit from studying closures a bit in javascript. It seems like you are trying to apply a traditional OO approach to js objects, and that won't give you the results you are expecting.
I would recommend reading over this post for an easy way to use closures:
http://howtonode.org/why-use-closure
Something like this:
<html>
<head>
<script type="text/javascript">
function createScheduleItemView(myId){
var _show = false
return {
setShow : function setShow(show) {
_show = show
},
update : function update(){
document.getElementById( myId +'-title').innerHTML = _show.title;
}
}
}
function createNowNextView(){
var _now = createScheduleItemView('now');
var _next = createScheduleItemView('next');
return {
publicVar : "Example",
update : function update(args) {
var myshow=args[0];
_now.setShow(myshow.now)
_now.update();
_next.setShow(myshow.next)
_next.update();
}
};
}
function runIt() {
nowNextView = createNowNextView()
args = []
showArgs = {
now : {title : "Beauty and the Beast"},
next : {title: "I did it myyyyyy way"}
}
args.push(showArgs)
nowNextView.update(args)
//Private variables can not be accessed
//console.log(nowNextView._now)
//undefined
//
//But anything you return in the object is public
//console.log(nowNextView.publicVar)
//Example
}
</script>
</head>
<body onload="runIt()">
<h3>Now Showing:</h3>
<p id="now-title"></p>
<h3>Up Next:</h3>
<p id="next-title"></p>
</body>
</html>

Related

How do we return function using module.exports in nodeJS?

How do we return function using module.exports in nodeJS?
file_1 book.js
module.exports = function() {
var points = 0;
return {
rate: function(value) {
points = value;
},
get: function() {
return points;
}
}
}
book.js is root file. We create two different instances but can not get the methods of root to script.js file.
file_2 main.js
var bA = require('./book.js');
var bB = require('./book.js');
bB.rate(10);
bB.get();
Output => can not find rate and get method.
Because the function returns an object with references to the rate and get functions, you need to execute it with a () on require like so:
var book = require('./book.js')();
book.rate(10);
book.get();
You're returning a function which returns an object.
Call the function and get the object
/*file_2 main.js*/
var bA = require('./book.js')();
var bB = require('./book.js')();
bB.rate(10);
bB.get();
Just in case if someone's facing same problem as me
I had something issue with my code. Lately realised I was making some API call and so return returned an object before fetching the value from API endpoint
I added async in front of function call and it worked!
var util=require('./app/Utils')
const url=await util.getInfo();
You can also provide a name to your anonymous export function as
module.exports.myfun = function() {
var points = 0;
return {
rate: function(value) {
points = value;
},
get: function() {
return points;
}
} }
Then use the function in another file as
var inc = require('./comp.js');
var mod = inc.myfun();
mod.rate(10);
console.log(mod.get());
In this way you don't need to have '()' at the time of required, though that option can also be used

Passing JavaScript to Closure in JavaScript

I'm learning how to actually use JavaScript. I've run into a situation where I'm getting an error. The error is: TypeError: 'undefined' is not an object (evaluating 'this.flagged'). I've narrowed down my code to where its happening. My code looks like this:
var flagged = false;
var intervals = [];
return {
flagged: flagged,
intervals: intervals,
createInterval : function (options) {
var defer = $q.defer();
if (this.throwsError) {
defer.reject('There was an error creating the interval.');
} else {
this.intervals.push(
$interval(function() {
console.log('here 1');
console.log(this.flagged);
},
1000
));
}
}
};
The error gets thrown at the: console.log(this.flagged); I'm guessing it has to do with the fact that "this" isn't visible. Yet, if "this" isn't visible, I'm not sure how to get the value for flagged. Can someone please explain to me what I need to do to get the value for flagged?
Thank you!
When you are using this inside $interval it won't be pointing to your original object, however, you can do this:
var flagged = false;
var intervals = [];
return {
flagged: flagged,
intervals: intervals,
createInterval : function (options) {
var defer = $q.defer(),
self = this;
if (this.throwsError) {
defer.reject('There was an error creating the interval.');
} else {
this.intervals.push(
$interval(function() {
console.log('here 1');
console.log(self.flagged);
},
1000
));
}
}
};
notice var self = this;
In JavaScript,
var flagged
will be a scoped variable, i think what you need here is a global scope variable for that, simply remove var from behind it.
flagged = false;
that should do the trick.

Can't instantiate object in javascript (node.js)

Hi can someone tell me why I can't instantiate the following class/object?
function Arbitrage(odds1, odds2, investment)
{
this.investment = investment;
this.odds1 = odds1;
this.odds2 = odds2;
this.arbPercent = function() {
return 1.0/this.odds1 + 1.0/this.odds2;
};
this.profit = function() {
return this.investment / this.arbPercent() - this.investment;
};
this.individualBets = function() {
return {
odds1bet : this.investment/this.odds1/this.arbPercent(),
odds2bet : this.investment/this.odds2/this.arbPercent()
};
};
};
module.exports = Arbitrage;
I'm calling it like this:
var utility = require('../businesslogic/utility');
...
router.post('/calculate', function(req, res)
{
var arbit = new utility.Arbitrage(req.body.odds1, req.body.odds2, req.body.investment);
res.json({
arbPercentage : arbit.arbPercent(),
profit : arbit.Profit(),
indvBets : arbit.individualBets()
});
});
The first line, var arbit = new utility.Arbitrage(...) is throwing the error.
It says TypeError: undefined is not a function
I've checked that utility isn't null or anything like that. Also all the constructor arguments are ok.
I'm not very familiar with javascript, any help would be appreciated. Thanks.
You're exporting your Arbitrage class directly, so after you're requiring it
var utility = require('../businesslogic/utility');
utility is actually your Arbitrage class, meaning that typeof utility === 'function'.
I can see two ways of fixing it.
1. Change the way you're requiring your Arbitrage class:
var Arbitrage = require('../businesslogic/utility');
// ...
var arbit = new Arbitrage(...);
2. Or change the way you're exporting it:
exports.Arbitrage = Arbitrage;
it's because of the way you exported it
you should use :
module.exports.Arbitrage = Arbitrage;
And then you can instanciate like this :
var Arbitrage = require('../businesslogic/utility');
var varbitrage = new Arbitrage();

Yet another JS newbie question

I just want to have a function VK.Share.Count(param1,param2) and property VK.Share.WorkUrl.
VK.Share.WorkUrl must be available from VK.Share.Count function. What is best way to do it? Can i just write:
VK.Share.Count = function(a,b) {
//blablablablablalbalblablal
VK.Share.WorkUrl = "sdfgfgadf";
}
VK.Share.WorkUrl = "lalalala";
var vk={
share:{
count:function(){},
WorkUrl:"lalala"
}
};
or
var vk={}
vk.share={};
vk.share.count=function(){
}
vk.share.WorkUrl="lalal";
You example will work and this will also work, if you are always calling the Count function like this VK.Share.Count();
VK.Share.Count = function(a,b) { this.WorkUrl = "foobar"; }
VK.Share.WorkUrl = "123";

Javascript Object Confusion

I've confused myself nicely here. My scenario is as follows:
function DesignPad() {
function EditBar() {
...
this.removeHandler = function() {
**// how do I call Dragger.removeAsset**
}
}
function Dragger(){
...
this.removeAsset = function() {}
}
this.init = function() {
this.editBar = new EditBar();
this.dragger = new Dragger();
}
}
var dp = new DesignPad();
...
I can't seem to call Dragger.RemoveAsset. I understand the why, my question is how do I call it?
I'm trying to keep like-things separated (e.g. Dragger / EditBar) but I seem to get all sorts of mixed up in my event handlers. Any suggestions, good reading materials, etc. on this stuff?
I found Douglas Crockford's Javascript to be the best introduction to JavaScript. Especialy videos for Yahoo, like: The JavaScript Programming Language where you can learn how exactly are objects created and inherited in JS.
Solution to you problem is:
function DesignPad() {
var that = this;
function EditBar() {
this.removeHandler = function() {
print("RemoveHandler");
that.dragger.removeAsset();
}
}
function Dragger() {
this.removeAsset = function() {
print("RemoveAsset");
}
}
this.init = function() {
this.editBar = new EditBar();
this.dragger = new Dragger();
}
}
var dp = new DesignPad();
dp.init();
dp.editBar.removeHandler();
But as others noticed you could refactor some things :).
To me it just looks like you should refactor that code to make it simpler.
I think that your issue comes from the fact that a nested function is private, so you can't access it from outside.
Is an instance of Dragger a 'property' of your DesignPad object? If so, you could pass a reference to that object into your removeHandler() method.
Try this:
function DesignPad() {
function EditBar(s) {
super = s;
this.removeHandler = function() {
alert('call 1');
super.dragger.removeAsset();
}
}
function Dragger(s){
super = s;
this.removeAsset = function() {
alert('call 2');
}
}
this.init = function() {
this.editBar = new EditBar(this);
this.dragger = new Dragger(this);
}
}
var dp = new DesignPad();
dp.init()
dp.editBar.removeHandler();
alert('end');

Categories

Resources