In the wapp.js I have the following class in JavaScript:
function Wapp() {
this.page = function($page_name) {
this.onLoad = function($response) {
}
}
this.navigate = {
changePage: function(link) {
// Ajax request to load the page
$.post(link, {}, function(response) {
// Code to display the page
});
}
}
}
in the app.js script I have the following code:
var wapp = new Wapp();
and I want to do this:
wapp.page('home').onLoad(function() {
// doSomething();
}
// When I call the method 'changePage'
wapp.navigate.changePage('home');
// at the end of the page load 'home' I want to call the function 'doSomething()' inside the 'onLoad' method
how should I define the methods within the class to make sure that at the end of a certain action (in this case at the end of the ajax call) to run the code defined within the 'onLoad' method in app.js?
You are able to assign a function as variable to your class when constructing it. You'll be able to call assigned function later in your code (e.g. in end of the other function)
https://jsfiddle.net/L8c2s6xr/
function func (functionToCall) {
this.functionToCall = functionToCall;
this.doSomething = function () {
this.functionToCall();
}
}
var f = new func (
function() {
alert('this works');
}
);
f.doSomething();
Related
I am trying to call one of the function in from .js file in angular whenever a route change happen.
This is my code in the javascript file and I need to call need to call the appData function in angular.
The console.logs for console.log(parsedJsonResponse); and console.log(appData) works fine and I am getting the JSON response.
window.dataLayer = (function () {
var dataCall = function () {
return new Promise((resolve, reject) => {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4) {
if (this.status == 200) {
resolve(this.responseText);
} else {
console.log(this.status + '.....' + this.statusText)
}
}
};
xhttp.open("GET", "http://localhost:4200/assets/sample.json", true);
xhttp.send();
})
}
dataCall().then((CallResponse) => {
getData(CallResponse)
});
window.addEventListener("load", function (event) {
appData();
})
var getData = function (cData) {
jsonResponse = cData.replace(/'/g, '"');
parsedJsonResponse = JSON.parse(this.jsonResponse);
var appData = parsedJsonResponse['content']['copy$$' + applicationContent];
console.log(parsedJsonResponse);
}
I am calling appData function in
var appData = function (applicationContent) {
var appData = parsedJsonResponse['content']['copy$$' + applicationContent];
console.log(appData)
}
return {
appData: appData,
dataCall: dataCall
}
}())
This is my code in angular calling the function.
When calling this function in angular I'm getting ReferenceError: parsedJsonResponse is not defined.
constructor(private router:Router) {}
ngOnInit(){
this.router.events
.filter(event => event instanceof NavigationStart)
.subscribe((event: NavigationStart) => {
dataLayer.appData();
})
};
What is going wrong? Thanks.
parsedJsonResponse variable should be declared outside all functions if you're going to use it in different functions. Otherwise parsedJsonResponse is private to getData function.
window.dataLayer = (function () {
var parsedJsonResponse;
// ...rest
Next you need to remove the function call inside window load event. appData() is getting called in window load but the data is still fetching and parsedJsonResponse has no content.
window.addEventListener("load", function (event) {
// appData();
})
In getData function remove this since jsonResponse is a private variable.
parsedJsonResponse = JSON.parse(jsonResponse);
I hope this will help.
EDIT:
Anyway I don't encourage using external js files. Try to use a service inside your Angular app.
UPDATE:
You are not passing the parameter in dataLayer.appData().
You are not handling the exceptions properly in the API request.
Try to declare parsedJsonResponse variable inside of a dataLayer function:
window.dataLayer = (function () {
var parsedJsonResponse;
/* rest of your code */
EDIT
The problem why this is happening, because your variable parsedJsonResponse gets its value, when ajax response comes from the server. It means, that it depends on async action. What you can do, is wait for response in promise. My suggestion is to keep that promise in new variable getAsyncData:
var getAsyncData = dataCall().then((CallResponse) => {
getData(CallResponse)
});
also don't forget to add that variable into return object:
return {
appData: appData,
dataCall: dataCall,
getAsyncData: getAsyncData
}
and you can use it in your angular app like so:
dataLayer.getAsyncData.then(() => {
dataLayer.appData();
});
One more thing I've noticed, that you are using applicationContent in getData function, but it haven't been initialized in your function dataLayer. The only usage on that variable in appData:
var appData = function (applicationContent) {
You should consider also initializing that variable on top of your function.
window.dataLayer = (function() {
var parsedJsonResponse;
var applicationContent;
/* rest of your code */
Here is the code, which I've made on top of your's with slight changes(here I sending response to jsonplaceholder server, so parsing that response is different, and also I've removed load event listener:
https://jsbin.com/birofufade/edit?html,js,console,output
I am trying to execute functions on click, Below is click button on HTML,
Insights.init() will execute on page load will give me some data from server, now with click on button, i need to pass variable to month function to filter data, and with click i want to execute all functions inside Insights()
var Insights = function() {
var initCheckColor = function(vari) {
console.log(vari);
}
var testFunction = function(vari) {
console.log('test');
}
return {
init: function() {
initCheckColor();
testFunction();
}
};
}();
jQuery(document).ready(function() {
Insights.init();
});
function month(vari) {
console.log("hoo");
return {
init: function() {
initCheckColor(vari);
testFunction();
}
};
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Month
Now problem is, i can see "hoo" printed on console when i click on link, but i also want to print it with execution of initCheckColor(vari) function, means i want output two times, but i could not output it,
How can i get output two times?
Problem: Is with this code
function month(vari) {
console.log("hoo");
//this block of code
return {
init: function() {
initCheckColor(vari);
testFunction();
}
};
// upto here
}
When you call the month function you are returning a object with a property named init Note: you are just returning a object and not executing the functions within the property. Also other issue is this property is a function which executes two other function, But those functions are not available in the current scope. As they are equal to Private methods for the Insights object.
Solution: Would be to re initialize the object with data just like how you are doing on page load.
I have fixed your code and added comments in the code where the changes were made.
var Insights = function() {
var initCheckColor = function(vari) {
console.log(vari);
}
var testFunction = function(vari) {
console.log('test');
}
return {
init: function(vari) { // have a input parameter during initialization.
initCheckColor(vari);
testFunction();
}
};
}();
jQuery(document).ready(function() {
Insights.init('something'); // I pass in the string "something" now this will be printed by the initCheckColor function.
});
function month(vari) {
console.log("hoo");
Insights.init(vari); // initialize the Insights object by passing in some value.
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Month
I want to call a JavaScript function that I made after a JQuery event has been called. I defined a function called scrambleDot earlier like this var scrambleDot = new function()
{ //my code }. Here's the code that I tried to use:
$('#reveal').click(function() {
$('.cover').css({'visibility':'hidden'});
$('#under').css({'visibility':'visible'});
})
$('#conceal').click(function() {
$('scrambleDot');
})
})
You have to call it just like:
scrambleDot();
To define a function, you don't need the new operator, so you should have:
var scrambleDot = function() { //my code }
If it still throws an error, it means it was defined in other scope. To make it globally accesible, do this when defining it:
window.scrambleDot = function() { //my code }
Cheers
We have to use new keyword, only when the function is used as a constructor for new Objects. So, the definition should not use new.
var scrambleDot = function() { //my code }
If the function need not be created dynamically, I would recommend
function scrambleDot() {
...
}
To invoke the function, simply do
scrambleDot();
For that call the function instead of selecting an element as:
$('#reveal').click(function() {
$('.cover').css({'visibility':'hidden'});
$('#under').css({'visibility':'visible'});
})
$('#conceal').click(function() {
scrambleDot();
});
And also, you write functions as:
function scrambleDot () {
// your code
}
It is a better practice than the variable one.
So, I've started playing with using an object to help organize my functions. So instead of having to make super long function names, I can just have sub functions in an object with the same prefix.
In my example, I'm using 'get' as a prefix, so I could call subfunctions by doing get.function(); and get.otherfunction();. However, I want to also be able to set a "default" function for the get object, so I can just call get(); by itself and it runs a function (but I don't want that function to run if I'm calling one of the subfunctions).
Here is the code I have thus far:
var get = {
default: function() {
alert('default function');
},
secondary: function() {
alert('secondary function');
}
}
You want to make an ordinary function, then add other functions as properties:
var get = function() { ... };
get.secondary = function() { ... };
If you want to, you could also write
get.default = get;
Or
get.default = function() { return get(); };
I'm using Class.js for creating classes.
I'm not getting the right context inside a method when invocked from a call back function
My code is
WordCloud = MyClass.extend({
init: function(data) {
var me = this;
(......).on("onComplete", this.draw);
},
show: function(word) {
alert(word)
},
draw : function(words){
console.debug(this); // prints element that triggred `onComplete` action
console.debug(words); // "Hi"
console.debug(me); // me is not defined
me.show(words) // Need to call this method
}
});
Problem is draw method is fired when an action is completed, but inside draw method this is not the actual class instance, but the element that triggred the callback action.
I can't pass exta arguments while calling this.draw as it is a call back function and onComplete has only one parameter.
How can I call the show method from draw?
If you do not have to support Internet Explorer 8 or lower, you can use bind():
init: function(data) {
var me = this;
(......).on("onComplete", this.draw.bind(this));
}
Otherwise, if you're already using jQuery, you can leverage $.proxy(), which works the same way:
init: function(data) {
var me = this;
(......).on("onComplete", $.proxy(this.draw, this));
}
I use a helper function for these cases.
function hitch(obj, func) {
return function() {
return obj[func].apply(obj, arguments || [])
};
}
To call it you would use hitch(this, 'draw'); instead of this.draw.
Or to make it even simpler you could add a simplified version to your base class
function hitch(func) {
var that = this;
return function() {
return that[func].apply(that, arguments || [])
};
}
And just call this.hitch('draw');.