jFeed problem: modifying global variable from success function - javascript

I am using jFeed to parse an RSS feed and I would like to modify an outside variable (or array) from the function executed upon "success". This is a simple version of the code:
var testVariable = "Original";
jQuery.getFeed({
url: rssFeed,
success: function(feed) {
testVariable = "New Value";
}
});
When I output "testVariable", it still has the original value "Original". Is something wrong with my code?
The purpose of this is to apply the same logic to an array instead of a variable, so I can load the feed's contents into a global Javascript array.
Any help will be greatly appreciated.

Related

How to fetch console.log data in jquery function

How to fetch console.log data in another function .we are getting value in console for example
triggerBtm: function(btmEvtObj){
$(document).trigger(btmEvtObj);
console.log(btmEvtObj);
},
Need to fetch value of "btmEvtObj" in another function in separate file. I need to fetch value in another function placed in separate file.
Why don't you just store that value in a variable. All javascript variables declared outside of a scope are global, so they can be accessed from any function.
var eventObjectFromTrigger;
triggerBtm: function(btmEvtObj){
$(document).trigger(btmEvtObj);
eventObject = btmEvtObj;
},
Then in your other function (whether its a separate file or not), just access it...
function foo(){
$(eventObjectFromTrigger).doSomething();
}
by the syntax it looks like triggerBtm is a method contained by another object. Add a return to the method body and access it in another file by calling the method from the object.
File 1
var yourObject = {
triggerBtm: function(btmEvtObj){
$(document).trigger(btmEvtObj);
console.log(btmEvtObj);
return btmEvtObj;
},
};
File 2
var yourValue = yourObject.triggerBtm();
Try Replacing The Whole Console with user-defined function:
var console = {log: function(data){
$("#console-1").append(JSON.stringify(data)+"\n");
},
error: function(data){
$("#console-1").append(JSON.stringify(data)+"\n");
},
warn: function(data){
$("#console-1").append(JSON.stringify(data)+"\n");
}};
This example will append all console log data in div#console-1.

call javascript page function inside ajaxed html

I have a page where i use jQuery to load some content into a div element
<div id="contents-box-in"></div>
jQuery code in page
$(document).ready(function() {
$("#contents-box-in").load("new-01.php", function() {
$('#contents-box-in').fadeIn(120);
});
var updateBoxData = function(data) {
$('#contents-box-in').fadeOut(100, function() {
$('#contents-box-in').html(data).fadeIn(130);
});
}
});
the content that i load is a form that needs to load a new page sending collected data from form
$('#form-buttons-next').click(function(e) {
var formData = new FormData($(this)[0]);
var formS = $.ajax({
url : 'new-02.php',
type : 'POST',
data : formData,
async : false,
cache : false,
processData : false,
contentType : false
});
formS.done(function(data) {
if (data != null) {
updateBoxData(data);
}
});
formS.fail(function(jqXHR, textStatus) {
alert("error");
});
});
since i do this in different step i would like to use a shared function contained in page that is loading the ajax content but i get updateBoxData is undefined
I guess that ajaxed content can't see parent container function
The easy way would be to load a different .js file containing shared function, i was wondering if is possible to access the updateBoxData from ajaxed contents
...i would like to use a shared function contained in page that is loading the ajax content but i get updateBoxData is undefined
I guess that ajaxed content can't see parent container function
No, that's not why. Your updateBoxData variable is scoped to the function it's declared in (your ready) callback. If you want it accessible globally, you'll need to make it global instead.
The problem is, though, the global namespace is already incredibly crowded. So if you put all of your useful functions there as globals, you're going to run into conflicts sooner or later.
For that reason, for now until browsers support ES2015 modules (which will take a while), I suggest giving yourself just one global symbol, something unlikely to conflict with other things, and assigning an object to it with properties for your various utility functions. E.g.:
var MyNiftyUtils = {
updateBoxData: function() {
// ...
}
};
Then you call that via MyNiftyUtils.updateBoxData. If the verbosity bothers you, no worries, just use a scoping function and assign it to a local:
(function() {
var u = MyNiftyUtils;
// ....
u.updateBoxData(/*...*/);
})();
(There are about 18 variations on that theme, this is just one of them.)
The function updateBoxData is defined inside a callback function you passed to .ready and hence its scope is limited to that function. Let us call this callback function Fx.
The click handler (the function passed to .click in the second part), which we call it Fy is defined outside of Fx and as a result does not have access to the variables defined in Fx (remember updateBoxData is a variable inside Fx).
That is why your code does not work. To get it working simply take updateBoxData out of the callback in .ready function:
$(document).ready(function() {
$("#contents-box-in").load("new-01.php", function() {
$('#contents-box-in').fadeIn(120);
});
});
function updateBoxData(data) {
$('#contents-box-in').fadeOut(100, function() {
$('#contents-box-in').html(data).fadeIn(130);
});
}
...
The rest is the same.

Loading Custom Component ViewModel from JavaScript file

I'm trying to create a custom component loader within knockout but I'm struggling with the view model. Essentially I want to remotely go grab both the HTML template and the JavaScript view model, but in this instance I don't want to use a traditional AMD module loader.
I've managed to get some of this working, specifically loading the HTML template but I can't figure out how to load the view model. Before I start here's my directory structure:
-- index.html
-- customerLoader.js
-- comps
   -- myCustom.html
   -- myCustom.js
So I've created my component loader like so. getConfig basically takes the name of the component and turns that into a path for the viewModel and the html template.
var customLoader = {
getConfig: function(name, callback) {
callback({ template: "comps/" + name + ".html", viewModel: "comps/" + name + ".js" });
},
loadTemplate: function(name, templateConfig, callback) {
console.log("loadTemplate", name, templateConfig);
$.get(templateConfig, function(data) {
callback(data);
});
},
loadViewModel: function(name, templateConfig, callback) {
console.log("loadViewModel", name, templateConfig);
$.getScript(templateConfig, function(data) {
callback(data);
});
}
};
ko.components.loaders.unshift(customLoader);
This successfully makes a request to load the template, which brings back some basic content. What I'm struggling with is the view model. I'm not sure what should be in the target of my JavaScript file?
I assumed that I'd want to return a function that would take some parameters, most likely a params object. However if I try and do this I get an error, telling me the JavaScript is invalid:
Uncaught SyntaxError: Illegal return statement
This is the current content I've got that is producing this error:
return function(params) {
console.log("myCustom.js", name, viewModelConfig);
// Add a computed value on
params.bookNum = ko.computed(function() {
switch(this.title()) {
case "A": return 1;
case "B": return 2;
case "C": return 3;
default: return -1;
}
});
//ko.components.defaultLoader.loadViewModel(name, viewModelConstructor, callback);
};
So ultimately I'm not sure how to achieve this, but I guess there are 3 basic questions that explain the gaps in my understanding:
What should my "view model" JavaScript file contain exactly? A function? An object? etc...
Do I need to call the ko.components.defaultLoader.loadViewModel at all?
Within my customLoader what should loadViewModel() be doing with the result of the jQuery callback? I'm not sure if I get back a JavaScript object, or just a string?
I'm open to achieve this in a different way if need be (e.g. not using jQuery but getting files a different way), but I don't want to use a module loader (e.g. require.js/curl.js in this instance).
First lets figure out what is happening...
From the docs:
This ($.getScript()) is a shorthand Ajax function, which is equivalent to:
$.ajax({
url: url,
dataType: "script",
success: success
});
And from jQuery.ajax():
...
dataType: ...
"script": Evaluates the response as JavaScript and returns it as plain text.
So your code is fetched, evaluated and then would have been returned as text, but evaluation first fails because you can't return if you're not within a function.
So what can be done? There are several options:
Use a module loader.
jQuery isn't a module loader, and as such it doesn't have the ability to parse fetched code and create a value / object from that code. A module loader is designed specifically for this task. It will take a script written in a specific pattern and "evaluate" it into a value (typically an object with 1 or more properties).
Change your script to a legal script
Because it's illegal to have a return statement in global code, your current code fails. You could however create a named function (or a variable with a function expression) and then use that name to reference that function. It could look like this:
function myCreateViewModel(param) {
// whatever
}
And the usage would be:
$.getScript(templateConfig, function() {
callback(myCreateViewModel);
});
The downside here is that if you ever go through that code path twice in the same page, your script will overwrite the old declaration. That might not ever be a problem, but it feels dirty.
Not use $.getScript(), use $.ajax() (or $.get()) with dataType: 'text' and evaluate yourself.
Remove the return from your code, and wrap it with an eval(). It will be evaluated as a function expression, the return value of the eval will be your function, and you could pass that directly to the callback:
$.get({
url: templateConfig,
dataType: 'text',
success: function(text) {
callback(eval(text));
}
});
This will work, but it will use the frowned upon eval(), which is exposing you to various risks.

Passing a local variable to a function that I can only make limited changes to

I am just starting to get into JavaScript and couldn't find an exact scenario like this yet on SO, so I'm going to try my luck. I have two functions in an external JS file which create video feeds on our website:
function getVideos() {
//gets a list of videos
}
//callback function automatically called by getVideos()
function response(jsonData) { //can't change this line
var resp = document.getElementById("resp"); //can change this line and any subsequent lines
//parses data and populates resp
}
Then, from the HTML side, we just call getVideos() and the video feed will be created and populated.
However, I want to be able to pass any element ID I want into response() so that we can create multiple video feeds in different places on the same page. The thing is I can't change the function declaration of response() to include another parameter. Or at least I'm not led to believe I can by the company hosting our videos.
I've tried wrapping response() with getVideos() and passing an element ID from there, but then response() doesn't get called, and the only solution I can think of is resorting to storing an element ID in a global variable, which I know is a no-no in general in JavaScript.
My question is: Do I just bite the bullet and use a global variable, or is there another way?
For more info, here is our JS code as it stands now (with the closure): http://www.thebearrocks.com/Other/js/videoFeed/createVideoFeed.js
And here is the tutorial on response() we're following from the host of our videos: http://support.brightcove.com/en/video-cloud/docs/making-media-api-calls-dynamic-script-tags
may be you can use arguments? like so:
function response(jsonData) { //callback function automatically called by getVideos()
var elemId = arguments.length<2 ? "resp" : arguments[1]+"";
var resp = document.getElementById(elemId);
//parses data and populates resp
}
or, declare second argument what has default value like this:
function response(jsonData, elemId) {
elemId = elemId || "resp";
var resp = document.getElementById(elemId);
//parses data and populates resp
}
in this case function can be called as with one or two arguments
I've tried wrapping response() with getVideos() and passing an element ID from there, but then response() doesn't get called, and the only solution I can think of is resorting to storing an element ID in a global variable, which I know is a no-no in general in JavaScript.
My question is: Do I just bite the bullet and use a global variable, or is there another way?
No. Not the id variable needs to become global, but your local response function needs to for getting called back from the JSONP script - you're going to create a closure.
You can "export" it by calling
window.response = mylocalResponseFunction; // you did name that local var "response"

Jquery $.get() manipulating data resulting from query in javascript

I have a $.get() statement, which returns this (result from a console.log()):
{"desc":"asdasda","dateD":"2012-08-31","dateE":"2012-09- 01","image":"fasdasdasd","categorie":"3"}
Now when I try, in Javascript, to manipulate the array, everything holds an undefined or null value:
var image = data.image;
desc = data.desc;
dateD = data.dateD;
dateF = data.dateE;
image = data.image;
categorie = data.categorie;
Note: the DateF= data.dateE is not a mistake.
Note2: Those statements are all held within the function (data){} function contained in the $.get().
All those assignments return undefined. What am I doing wrong? I have read and re-read the official jQuery doc, without success.
Make sure you set the dataType of the return to json.
If you don't do this, the result data may be a string and you will need to use JSON.parse(data) to turn it into a usable object.
For example:
$.get(url, getData, function(data){
//your fn...
}, 'json');

Categories