newbie Javscripter here. I'm trying to get some practice with modules and I'm hitting a wall. I'm trying to get the controller module to access the wagerAmount(input by user) from the UIControl module with minimal success. My relevant code is as follows:
var UIControl = (function() {
return {
getWager: function() {
return {
wagerAmount: document.getElementById('wager').value
};
}
};
})();
var controller = (function(UICont) {
var topics = ['sports', 'history', 'technology', 'music', 'movies'];
var wager = UICont.getWager();
var changeClass = function() {
document.getElementById('bet').addEventListener('click', function() {
console.log(wager);
for (var i = 0; i < topics.length; i++) {
if (document.getElementById(topics[i]).classList[1] == 'select') {
activateAnswers();
}
}
});
}
})(UIControl);
When I run this, console.log(wager) prints a empty string, {wagerAmount: ""}. If I declare wager inside the changeClass function, the same thing happens. However, if I declare wager inside the click event, it prints the number input by the user. BUT, the topics variable, declared in the controller is being accessed just fine by the click event. The main problem here is when I need to add the functionality to multiple click events, I would have to declare a new variable in each click event to access the same function, which sounds like bad practice. So what's going on here?
Ok, so after spending a couple hours last night trying to figure this out, I quickly figured out the solution this morning after some coffee. In case anyone else has this problem I'll post my solution, and if someone else comes up with something else, they can post as well.
Instead of declaring wager in the controller anywhere, I created a new function inside controller:
var retrieveWager = function() {
return {
wager: UICont.getWager().wagerAmount
};
}
and then could access it in any of the click events like this:
retrieveWager().wager;
Related
I use angularJS(1.4) for frontend only.
I have passed the JS-class DummyClass to an angularJS-Service called TLSService, and I added this service to an angularJS-Controller named mLxController.
I'm having problems accessing variables and methods of the DummyClass from the mLxController.
For example, as you will see in the code below, I can't retrieve a class variable String.
I use window.alert(String) to check that.
Instead of the String from the DummyClass, 'undefined' is displayed in the window.
I think it's worth mentioning, that when adding the window.alert("DummyClass calls.") in the constructor of the DummyClass, the alert will immedialtely be shown after loading the corresponding URL.
That's the code of the mLxController.js :
angular.module('mApp')
.controller('mLxController', function('TLSService', $scope, $state, $stateParams){
...
//this function is called in `index.html`
$scope.callTLSService = function(){
window.alert(TLSService.response);
}
...
});
Here's the code for dummyClass.js :
class DummyClass {
constructor() {
this.response = "Hi Controller! Service told me you were looking for me.";
}
}
Here's tlsService.js :
angular.module('mApp').service('TestClaServScript', function(){new DummyClass()});
UPDATE:
I have managed to make the DummyClass usable to the mLxController.
Although I'm pretty sure that my solution is not recommendable practice.
Basically, I moved the DummyClass into the same file as the TLSService.
Also, DummyClass and it's path isn't mentioned in the main index.html, anymore.
Accordingly, tlsService.js looks like this, now:
angular.module('mApp').service('TestClaServScript', function(){
this.clConnect = function(inStr){
var mDummy = new DummyClass(inStr);
return mDummy;
}
});
class DummyClass {
constructor(inStr){
this.inStr = inStr;
this.response =
"DummyClass says: \"Hi Controller! Service told me you were looking for me.\"";
this.charCount = function(inStr){
var nResult = inStr.length;
var stRes = "btw, your String has "
+(nResult-1)+", "+nResult+", or "+(nResult+1)+" characters.\nIDK."
return stRes;
}
}
}
and mLxController.js:
angular.module('mApp')
.controller('mLxController', function('TLSService',$scope,$state, $stateParams){
...
$scope.makeDummyCount = function(){
var mDummy = TestClaServScript.clConnect("This string is for counting");
window.alert(mDummy.charCount(mDummy.inStr));
}
...
});
There must be a way to properly import DummyClass, so that I can keep separate files.
I will do some more research and I will keep trying.
UPDATE 2: Problem solved
The provided answer to my question helped me implementing TLSService in the originally planned way.
I'd like to post the final version of the code here, in hope that it will help some beginner, like I am.
tlsService.js:
angular.module('mApp').service('TLSService', function(){
this.mCwParam = function(inputStr){
return new DummyClass(inputStr);
}
});
DummyClass stays the same like I posted it in the first Update, but it has its own file dummyClass.js, again.
mLxController.js:
angular.module('mApp')
.controller('mLxController', function('TLSService', $scope, $state, $stateParams){
...
//this function is called in the mLx-view's `index.html`
$scope.askDummyCount = function(){
var mService = TLSService.mCwParam("String, string, string, and all the devs that sing.");
window.alert(mService.charCount());
}
...
});
Also, TLSService and DummyClass ar added in the apps main index.html.
A problem in your original setup is when you register your class as a service, you're not returning the instance of the class:
function(){new DummyClass()}
Should be:
function(){return new DummyClass()}
Autoreturning only works when you don't use curly braces, like
() => new DummyClass()
After reading the following article,
http://javascriptplayground.com/blog/2012/04/javascript-module-pattern/
I have decided to start implementing modules in my JS.
Unfortunately, the module I am using does not seem to be keeping the private variable private,
var popoverOptionsModule = (function() {
var _stopAskingList = [];
var addToStopAskingList = function(itemToAdd) {
if (_stopAskingList.indexOf(itemToAdd) === -1){
_stopAskingList.push(itemToAdd);
}
}
var getStopAskingList = function() {
return _stopAskingList;
}
return {
addToStopAskingList: addToStopAskingList,
getStopAskingList: getStopAskingList,
};
})();
popoverOptionsModule._stopAskingList = 4;
console.log(popoverOptionsModule._stopAskingList);
As you can see, I am able to change the value of
popoverOptionsModule._stopAskingList and log the update to the console... I thought this was not supposed to happen. Thanks for your help!
JS is completely dynamically typed, so when you have the line
popoverOptionsModule._stopAskingList = 4;
You've just created this variable and assigned it a value, hence why the next line succeeds. If you didn't have this line, then the subsequent console.log would report undefined. This code would work too
popoverOptionsModule._abc = 4;
console.log(popoverOptionsModule._abc);
Remember that this isn't actually a private variable in the same way that OO languages implement protection levels, rather it's just an API pattern that attempts to hide it from the caller.
I want to add a variable or a function to my mdDialog. Im not to sure on how to create a custom mdDialog, Im new to angularjs.
This is my mdDialog:
vm.dialog_up = function() {
vm.dis = true;
alert = $mdDialog.alert()
.title('Attention, ')
.content('Do you want to edit your Information?')
.ok('Close');
$mdDialog
.show( alert )
.finally(function() {
alert = undefined;
});
}
I want to maybe add a function to the .ok button.
JavaScript is a very liberal language and it allows you to add properties and methods to objects. For example:
var modal = {};
modal.x = 5;//this assigns the value of `5` to the newly attached property `x`
modal.testMethod = function() {
//Do something here
}
PS:
Though personally, I think that modifying framework objects can cause side effects.
I have created this:
var where = function(){
sym.getSymbol("Man").getPosition()
}
console.log(where);
if (where()<=0){
var playMan = sym.getSymbol("Man").play();
} else {
var playMan = sym.getSymbol("Man").playReverse();
}
This is for Edge Animate hence all the syms. I am trying to access the timeline of symbol Man, then if it is at 0 play it. But it isnt working and the reason, I think, is that I have an incomplete understanding of how a var works. In my mind I am giving the variable 'where' the value of the timeline position of symbol 'Man'. In reality the console is just telling me I have a function there, not the value of the answer. I have run into this before and feel if I can crack it I will be a much better human being.
So if anyone can explain in baby-language what I am misunderstanding I would be grateful.
Thanks
S
var where = function () { ... };
and
function where() { ... }
are essentially synonymous here. So, where is a function. You are calling that function here:
if (where()<=0)
However, the function does not return anything. You need to return the value from it, not just call sym.getSymbol("Man").getPosition() inside it.
That, or don't make it a function:
var where = sym.getSymbol("Man").getPosition();
if (where <= 0) ...
The value will only be checked and assigned once in this case, instead of updated every time you call where().
Try
var where = function()
{
return sym.getSymbol("Man").getPosition();
};
Your code wasn't returning anything.
var where = function() {
return sym.getSymbol("Man").getPosition()
}
console.log(where);
if(where()<=0) {
var playMan = sym.getSymbol("Man").play();
} else {
var playMan = sym.getSymbol("Man").playReverse();
}
how can i access a variable that was intialsed in a function, but the main.name is giving me a null value, i know the value is initliased in the function, or on main, but not in the feed!! this is my example,
var main = Titanium.UI.createWindow();
var feed = Titanium.UI.createWindow({
title:'feeds',
url:'main_windows/feeds.js',
barImage:'bg_content.gif',
username:main.name //im trying too access this varibale from main.
});
Ti.App.addEventListener('grantEntrance',function(event)
{
main.title ='Welcome'+event.username;
main.url = 'main_windows/main.js';
main.name = event.username; // this is where the varibale is intialised
main.email = event.email;
main.barImage='bg_content.gif';
});
sorry if this seems like a stupid question but im a newbie to javascript, so just tell me to delete it. i was wondering if you can turn it into a gloab or something.
You're trying to get variable that is not initialized yet. Since you're assigning main.name in a callback of event it will be initialized only after that event is fired. I'm not sure what's the logic of you'r application, but I guess you're able to initialize window inside this callback:
Ti.App.addEventListener('grantEntrance',function(event) {
main.title ='Welcome'+event.username;
main.url = 'main_windows/main.js';
main.name = event.username;
main.email = event.email;
main.barImage='bg_content.gif';
var feed = Titanium.UI.createWindow({
title:'feeds',
url:'main_windows/feeds.js',
barImage:'bg_content.gif',
username:main.name
});
});
Or, just set username property of the window inside callback:
var feed = Titanium.UI.createWindow({
title:'feeds',
url:'main_windows/feeds.js',
barImage:'bg_content.gif',
});
Ti.App.addEventListener('grantEntrance',function(event) {
main.title ='Welcome'+event.username;
main.url = 'main_windows/main.js';
main.name = event.username;
main.email = event.email;
main.barImage='bg_content.gif';
feed.username = main.name
});
Also, from personal experience: Titanium is not the best way to "fill the power" of js: some of methods are running asynchroniusly, and it causes weird issues. So if you're newbie it could be a pain in the ass..
Anyway good luck :)