javascript global var from ajax function - javascript

I'm using dajaxice to retrieve a json attribute - that I would like to be global. I'm not sure why my global var is always "undefined":
var recent_id;
$(function(){
recent_id = Dajaxice.ticker.get_home_timeline(get_home_timeline_callback);
alert(recent_id);
});
function get_home_timeline_callback(data){
if(data==Dajaxice.EXCEPTION){
alert('Error! Something happens!');
}else{
var parsed = JSON.parse(data.home_timeline);
var parsed_id = {'parsed_id':parsed[0].id_str};
console.log(parsed_id);
}
return parsed_id;
}
#dajaxice_register
def get_home_timeline(request):
home_timeline = oauth_req(
'http://api.twitter.com/1/statuses/home_timeline.json?count=1',
settings.TWITTER_TOKEN_KEY,
settings.TWITTER_TOKEN_SECRET
)
return simplejson.dumps({'home_timeline': home_timeline })
Is this a bad way to access a var to be used in another ajax function?

Seems like async issue. Modify your get_home_timeline_callback function as following
function get_home_timeline_callback(data){
if(data==Dajaxice.EXCEPTION){
alert('Error! Something happens!');
}else{
var parsed = JSON.parse(data.home_timeline);
var parsed_id = {'parsed_id':parsed[0].id_str};
console.log(parsed_id);
}
//debug
alert(parsed_id);
//since the value has come, now assign it to the global variable
recent_id = parsed_id;
}

It seems like the variable scope issue. The scope of the variable parsed_id is declared within the else statement within the { }, so its scope is within the else statement. And when you return the parsed_id outside the brackets it might be giving undefined.
Go through the scope of variables explanation here
Change your function as shown below.
function get_home_timeline_callback(data)
{
var parsed_id = "";
if(data==Dajaxice.EXCEPTION)
{
alert('Error! Something happens!');
}
else
{
var parsed = JSON.parse(data.home_timeline);
parsed_id = {'parsed_id':parsed[0].id_str};
console.log(parsed_id);
}
return parsed_id;
}
Now here the scope of the variable parsed_id can be accessed anywhere within function.
Hope this solves your problem if not sorry. This was my assumption that the scope might be affected.

Related

Passing values from an object inside a function

I have been working all day trying to pass the value of "returnData.salary" inside the "readData" function to
the object inside the "calculateTax" function which is suppose to take the salary value and calculate state and federal taxes. I am stumped, I can't find anything on the internet which provides a good example for me to work with. The examples are either way to simple or super complex. Any help would be appreciated.
I apologize in advance if I did not submit this question in the correct format. This is my first time asking for help on stackoverflow.
function readForm() {
var returnData = {};
returnData.name = $("#name").val();
returnData.lastName = $("#lastName").val();
returnData.age = $("#age").val();
returnData.gender = $("[name=gender]:checked").val();
returnData.salary = $("#salary").val();
returnData.isManager = $("#isManager").val();
returnData.myTextArea = $("#myTextArea").val();
$("#name2").text(returnData.name);
$("#lastName2").text(returnData.lastName);
$("#age2").text(returnData.age);
$("#gender2").text(returnData.gender);
$("#salary2").text(returnData.salary);
$("#myTextArea2").text(returnData.myTextArea);
if ($(isManager).is(':checked')) {
$("#isManager2").text("Yes");
}
else {
$("#isManager2").text("No");
}
//$("#employeeForm")[0].reset();
} //end of readForm function
function calculateTax() {
console.log("Button Works");
var calculateTax = {
state: function(num) {
num *= 0.09;
return num;
}
, federal: function(num) {
if (num > 10000) {
num *= 0.2;
return num;
}
else {
num * 0.1;
return num;
}
}
, exempt: true
};
}
//Invoke readForm function when the submit button is clicked.
$(document).ready(function () {
$("#btnSubmit").on("click", readForm);
$("#btnCalculate").on("click", calculateTax);
})
</script>
Well, simply put; you can't. Not like this anyway. Or, at least not pass the value to the function directly.
You are using global functions right now, which are not inside a class. If it was inside a class, you could instantiate the class and save it to this (which would be the class' instance). However, I'm assuming classes are a bit over complicated in this case. What you could do, is set variables globally so all functions can use them, like this;
//declare the global variable so it exists for every function
var returnData = {};
function readForm() {
//We do NOT redeclare the "var" again. It's global now.
returnData = {}; //Reset the global variable when this function is called
returnData.name = $("#name").val();
returnData.lastName = $("#lastName").val();
returnData.age = $("#age").val();
returnData.gender = $("[name=gender]:checked").val();
returnData.salary = $("#salary").val();
returnData.isManager = $("#isManager").val();
returnData.myTextArea = $("#myTextArea").val();
//Rest of your function
}
function calculateTax(){
console.log(returnData) //works here
}
Note that you do overwrite global variables, so it's best to reset them on every function call. You might get old data stuck in there, otherwise.

How can I redefine a variable based on a functions result? (javascript)

I have something like the following:
$('#country1').change(function() {
var hrc = "Yes";
if (className == "HR") {
var hrc = "Yes";
return true;
} else {
var hrc = "No";
return false;
}
Then I am pulling this with JSON into a SP List like:
$('.submitdataAccounts').on('click', function() {
var data = {
__metadata: {
'type': 'SP.Data.ChangeOfAddressListListItem'
},
"high_risk_country": hrc,
};
This part works correctly as everything else in the form posts successfully into the list
If I leave it as a static variable at the top of the page it passes correctly but does not work if it's based on the fuction.
Thanks,
Declare the variable outside the functions, so it is a global variable, and then you can acces it everywhere in your code. If you give a global variable an another value, it is redefined and gets that value until an another value change.

Local variable lost in closure

The variable cont is being lost in the following:
__factory.setupMenu = function(cont,input,multiSelect,exclusive,popMenu){
var __menu = {multiSelect:multiSelect};
spotter.events.setEventTrigger(input,'change');
__menu.exclusive = {inputs:[],values:exclusive||[],simpleValues:[]};
alert(cont);//<-- is defined here
window.popSelectComponent= cont;//<-- saved it globally to test reference
return function(ajaxResult){
var data = ajaxResult.template.response||[];
var info = {},l=data.length;
while(--l > -1){
info[String(data[l].value)] = data[l].abbr||data[l].name;
}
var textTarget;
alert(window.popSelectComponent);//<-- this is defined as expected
alert(cont);//<-- is now undefined
alert(input);//<-- this is defined as expected
if(!(textTarget = cont.querySelector('[data-pop-selected]'))){textTarget = cont;}
if(!input.popSelectTemplate){
spotter.data.bindElementToInput(textTarget,input,function(content){
content = content.split(',');
var l=content.length;
while(--l > -1){
content[l] = info[content[l]];
}
content = content.join(',');
return (content.length ? content : 'ignore');
});
}
else{
var cont = document.createElement('SPAN');//<-- PROBLEM IS CAUSED HERE. HOISTING IS CAUSING CONT TO BE UNDEFINED AT CLOSURE START
cont.className="multi-select";
cont.appendChild(cont);
//removal function
var remove = (function(input){
return function(e){
var evt = e ? e:window.event;
if (evt.stopPropagation) evt.stopPropagation();
if (evt.cancelBubble!=null) evt.cancelBubble = true;
if(input.value !== input.spotterPopSelectDefaultValue){
input.value = input.value.removeListValue(this.getAttribute('data-id'),',');
spotter.deleteElement(this);
if(input.value === '' && input.value !== input.spotterPopSelectDefaultValue){
input.value = input.spotterPopSelectDefaultValue;
input.eventTriggers['pop-select-change']();
}
}
};
}(input));
input.spotterPopMenuOptions = __menu;
input.addEventListener('pop-select-change',(function(cont, info, template){
return function(){
var HTML = '';
this.value.split(',').forEach(function(val){
HTML += template.replace('$[ID]', val).replace('$[NAME]', info[val]);
});
cont.innerHTML = HTML;
spotter.castToArray(cont.children).forEach(function(el){ console.log('option el',el); el.addEventListener('click',remove,false); });
console.log('input.spotterPopMenuOptions',input.spotterPopMenuOptions);
};
}(cont, info, input.popSelectTemplate.innerHTML)),false);
}
....
So running var func = __factory.setupMenu(...)({template:{}}) I am receiving an error message that cont is undefined while window.popSelectComponent is defined like expected. I tried changing the name of cont thinking I was overlooking something that was changing the value but that did not work either.
After running the function, I check cont in the context that initially created this closure and cont is still defined so it is not a matter of an object reference being lost as far as I can tell.
Perhaps a highly simplified example would make the problem more obvious:
var outer = function(theVariable) {
console.log("In the outer function, theVariable is", theVariable);
var inner = function() {
console.log("In the inner function, theVariable is", theVariable);
if (false) {
var theVariable = 2;
}
};
inner();
}
outer(1)
In the outer function, theVariable is 1
In the inner function, theVariable is undefined
As you have seen, the fact that a different variable with the same name has been declared (even though not initialized) in the inner function hides the properly initialized variable in the outer function that would have otherwise been visible.
You might think that because the variable is declared in a block, it would not affect other parts of the function. No, var is function scoped, not block scope.
This flaw has been addressed in modern versions of Javascript, and the var keyword has been superseded by let, which has the block scope you were expecting. var is kept for backwards compatibility, but you should not use it in new code.

Why I can't pass parameter into .then function (AngularJS)?

I have this function
$scope.updateValue = function(key, selectedProductname, numberUsed){
var selectedKey = key;
var selectedProductname = selectedProductname;
var numberUsed = numberUsed;
var useageRef = ref.child('/useage/');
var updateObj = $firebase(useageRef);
var myData = {
productName : selectedProductname,
numberUsed : numberUsed
}
var decrementLocation = inventoryRef.child(key + '/amount')
updateObj.$push(myData).then(
decrementLocation.transaction(function (current_value, numberUsed) {
console.log(numberUsed);
return (current_value || 0) - 1;
})
);
}
I pass "numberUsed" into $scope.updateValue and use it inside myData and then push it to the server and there is no problem with that but when I use it at this line "decrementLocation.transaction(function (current_value, numberUsed) {" and then I try to console.log(numberUsed); the console says undefined. Why? and how can I use numberUsed in this line "decrementLocation.transaction(function (current_value, numberUsed) {" ? how to code it successfully?
There is a number of things going on here.
First of all, in the following code:
decrementLocation.transaction(function (current_value, numberUsed) {
console.log(numberUsed);
return (current_value || 0) - 1;
})
You are re-declaring numberUsed as the second parameter of the .transaction() callback function. Thus, whatever numberUsed was outside of this small function does not matter. If you want to use the var from the surrounding function, you would need to do:
decrementLocation.transaction(function (current_value) {
console.log(numberUsed);
return (current_value || 0) - 1;
})
Second of all, there is no closing ; to your .transaction() function. I don't think it will materially affect your operating here, but cannot be sure. This should be run through jslint/jshint.
Third, you are redeclaring numberUsed inside the entire surrounding $scope.updateValue() function.
$scope.updateValue = function(key, selectedProductname, numberUsed){
var numberUsed = numberUsed;
So you are declaring a new variable numberUsed, whose value will be, well, numberUsed, but it is a new var, so it should be set to undefined. If it is set to anything at all, that would be surprising. If you need the var, then you should do:
$scope.updateValue = function(key, selectedProductname, numberUsed){
var nu2 = numberUsed;
or something similar. But even then, why bother to redeclare the var? It is copied by value anyways.
A good linter will catch any of this.

Confused as to why I'm losing scope of a variable using jquery/jsremoting in Salesforce

The code looks fine to me which is why I'm confused with the G_SResult variable losing scope. It's declared globally above the ready function but that isn't visible in the screenshot. In the screenshot you will see 4 highlighted alert expressions. The one with the red dot is where it returns undefined. The other alerts return the right value.
Screenshot of the code.----> http://i.imgur.com/nNIBk.png
function Savedat(){
var Surveyz=new Survey();
Surveyz.Name=j$('#survey_name').val();
var SResult;
var QuestionOrder=1;
var id;
//alert(G_SResult+'----first');
//alert(typeof G_SResult === 'undefined');
Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.SV_CreateSurvey.insertSurvey}'
,Surveyz
,function(Survey_result, event){
console.log(Survey_result);
SResult=Survey_result;
j$('[name="p_Q"]').each(function(){
elId=this.id;
var elNum=elId.substring(1);
QType=j$('input[name=ctrlSel'+elNum+']:checked').val();
Quest=new Question();
Quest.Question__c=j$(this).val();
Quest.Question_Input_Type__c=QType;
SResult=Survey_result;
G_SResult=SResult;
alert(G_SResult+'---1');
Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.SV_CreateSurvey.insertQuestion}'
,Quest
,function(Question_result, event){
console.log(Question_result);
var SQLink=new SurveyQL();
SQLink.SG_Survey__c=SResult;
SQLink.Survey_Question__c=Question_result;
SQLink.QOrder__c=(QuestionOrder);
Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.SV_CreateSurvey.insertSurveyLink}'
,SQLink
,function(SurveyLink_result, event){
console.log(SurveyLink_result);
});
j$('[name="A'+elNum+'"]').each(function(){
SA=new SurveyAnswer();
SA.Answer__c=j$(this).val();
SA.Survey_Question__c=Question_result;
Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.SV_CreateSurvey.insertAnswer}'
,SA
,function(Answer_result, event){
console.log(Answer_result);
});
});
QuestionOrder++;
});
alert(G_SResult+'----2');
});
alert(G_SResult+'----3');
});
setTimeout(function(){Work();}, 1000);
}
In case anyone ever comes across this for whatever reason, the solution was this...
(Both code blocks have been edited as a working example)
function Work()
{
//Semaphore like
if (typeof G_SResult === 'undefined')//(G_SResult == undefined)
{
//run stuff here
setTimeout(function(){Work();}, 1000);
}
else
{
alert(G_SResult+'----5');
//G_SResult = null;
}
}
Looks like Visualforce.remoting.Manager method is Asynchronous.
The variable exists in another scope. It is declared in the anonymous function
function Savedat(){
// [ Code .. ]
j$('[name="p+Q]').each(
function(){
// [ Code.. ]
G_SResult = 999;
// G_SResult didnt exist and is therefore declared locally.
// It implies "var G_SResult = 999"
}
);
// G_SResult undefined here.. because it is outside the scope where it was defined.
}
And doesnt exist in the Savedat(){} function

Categories