jQuery using values from inside each function - javascript

The code I wrote below works, but the variables I named within the each function are not defined after the function completes.
jQuery.each($myObject, function(i, val) {
ce = $(this).attr('class');
if (i === 0) {
step1complete = true;
if (/incomplete/i.test(ce)) {
var step1complete = false
}
console.log('step1' + step1complete);
} else if (i === 1) {
step2complete = true
if (/incomplete/i.test(ce)) {
var step2complete = false
}
console.log('step2' + step2complete);
} else if (i === 2) {
step3complete = true
if (/incomplete/i.test(ce)) {
var step3complete = false
}
console.log('step3' + step3complete);
}
});
if (step1complete === true && step2complete == false && step3 == false) {
console.log('Youre Just Starting Out I see');
} else {
console.log('You got one step done now theres more!');
}
However, its saying the variables I set in the each function are not defined even though I see them in the console during the loop.

Don't use var as it will scope it inside the function that is enclosed. Instead, bring them out, just the var part.
var step1complete;
var step2complete;
var step3complete;
jQuery.each($myObject, function(i, val) {
ce = $(this).attr('class');
if (i === 0) {
step1complete = true;
if (/incomplete/i.test(ce)) {
step1complete = false
}
console.log('step1' + step1complete);
} else if (i === 1) {
step2complete = true
if (/incomplete/i.test(ce)) {
step2complete = false
}
console.log('step2' + step2complete);
} else if (i === 2) {
step3complete = true
if (/incomplete/i.test(ce)) {
step3complete = false
}
console.log('step3' + step3complete);
}
});
if (step1complete === true && step2complete == false && step3 == false) {
console.log('Youre Just Starting Out I see');
} else {
console.log('You got one step done now theres more!');
}
If you don't want to pollute the global scope, use an IIFE:
(function () {
var step1complete;
var step2complete;
var step3complete;
jQuery.each($myObject, function(i, val) {
ce = $(this).attr('class');
if (i === 0) {
step1complete = true;
if (/incomplete/i.test(ce)) {
step1complete = false
}
console.log('step1' + step1complete);
} else if (i === 1) {
step2complete = true
if (/incomplete/i.test(ce)) {
step2complete = false
}
console.log('step2' + step2complete);
} else if (i === 2) {
step3complete = true
if (/incomplete/i.test(ce)) {
step3complete = false
}
console.log('step3' + step3complete);
}
});
if (step1complete === true && step2complete == false && step3 == false) {
console.log('Youre Just Starting Out I see');
} else {
console.log('You got one step done now theres more!');
}
})();
Definition:
IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined. It is a design pattern which is also known as Self-Executing Anonymous Function and contains two major parts. The first is the anonymous function with lexical scope enclosed within the Grouping Operator (). This prevents accessing variables within the IIFE idiom as well as polluting the global scope.

Related

Communication issue between functions into JS and JSX files

I have made this function into a JS file...
function getColors(isPick, isForecolor)
{
var chosenFunction = 'getColor(' + isPick + ', ' + isForecolor + ')';
csInterface.evalScript(chosenFunction, function(result)
{
if(result !== 'undefined')
{
if (isForecolor == true){
foregroundHexColor = result;
// etc...
}
else
{
backgroundHexColor = result;
//etc..
};
};
});
};
which get a hexadecimal color value from this function from a JSX file.
function getColor(isPick, isForecolor)
{
var color_PickerCase;
var decimal_Color;
var hexadecimal_Color;
if (isForecolor == true)
{
color_PickerCase = app.foregroundColor.rgb.hexValue;
}
else
{
color_PickerCase = app.backgroundColor.rgb.hexValue;
};
if (isPick == true)
{
if (app.showColorPicker(isForecolor)){
decimal_Color = color_PickerCase;
hexadecimal_Color = decimal_Color.toString(16);
}
else
{
return;
};
}
else
{
decimal_Color = color_PickerCase;
hexadecimal_Color = decimal_Color.toString(16);
};
return hexadecimal_Color;
};
In some way it works, but for some reason I have to do the same thing two times so to get the value!!! Any idea why is this happening?
Thank you for your time!!!
UPDATE: A correction, it works only at first click. Then needs to clicked two times so to get the value!!!
Well, here is the solution...
function getColor(isPick, isForecolor)
{
var color_PickerCase;
var decimal_Color;
var hexadecimal_Color;
if (isPick === true && app.showColorPicker(isForecolor) === false)
{
return;
}
if (isForecolor === true)
{
color_PickerCase = app.foregroundColor.rgb.hexValue;
}
else
{
color_PickerCase = app.backgroundColor.rgb.hexValue;
}
decimal_Color = color_PickerCase;
hexadecimal_Color = decimal_Color.toString(16);
return hexadecimal_Color;
};
As joojaa from graphicdesign said, I was asking for the color before picking it and I was getting the color form the last time!!!

Why my array data does not print in render function REACTJS?

I am stuck in reactjs.
I have a function in which there is an array containing some values, but when I want to access that array in render function and pass it using props to another function, it returns a blank array.
what should I do to resolve this problem?
Like this:
In Function:
this.usersAnswerXML = ["ID0", "ID1", "ID2"]
In Render:
this.usersAnswerXML = []
Here is my code, what am I doing wrong?
handleSplitContentClick(contentId, selectionType) {
let isCorrect
if (selectionType == 'selected') {
const index = this.correctAnswers.indexOf(contentId);
if (index > -1) {
this.userCorrectAnswers.push(contentId);
if (this.correctAnswers.length === this.userCorrectAnswers.length &&
this.userUncorrectAnswer.length == 0) {
isCorrect = this.correct
} else {
isCorrect = this.incorrect
}
} else {
this.userUncorrectAnswer.push(contentId);
isCorrect = this.incorrect
}
} else if (selectionType == 'disselected') {
const index = this.correctAnswers.indexOf(contentId);
if (index > -1) {
this.userCorrectAnswers.splice(index, 1);
isCorrect = this.incorrect
} else {
this.userUncorrectAnswer.splice(index, 1);
if (this.correctAnswers.length === this.userCorrectAnswers.length &&
this.userUncorrectAnswer.length == 0) {
isCorrect = this.correct
} else {
isCorrect = this.incorrect
}
}
}
this.userAnswerXML = this.userCorrectAnswers.join(',')
this.usersAnswerXMLs = this.userAnswerXML + ',' +
this.userUncorrectAnswer.join(',')
this.usersAnswerXML = this.usersAnswerXMLs.split(',')
console.log(this.usersAnswerXML)
if (window.uaXML) {
this.userAnswerXML = window.uaXML
console.log(this.userAnswerXML + "data")
}
// this.usersAnswerXML = window.uaXML
console.log(window.uaXML)
this.userAnswerXML = "<smans type='4'><div id='textID0' userAns='" +
this.usersAnswerXML + "'></div></smans>"
$("#special_module_user_xml").val(this.userAnswerXML )
console.log(this.usersAnswerXML)
}
} // Editor's note: this is an extra curly brace
render() {
if (this.props.remedStatus) {
console.log(this.usersAnswerXML)
console.log("inside remed")
return (
<HotspotRemed
xml={this.receivedXML}
userXml={this.usersAnswerXML}
correctAnswer ={this.ansString}
type={this.splitType}
/>
)
} else {
return (
<div className="previewtemplate" style ={template}>
{this.templateArea(this.state.templateType)}
</div>
);
}
}
} // Editor's note: another extra curly brace
} // Editor's note: another one again

There is a line in the Javascript cometd chat client distributed in 3.1 that I don't understand

My question is about the _metaConnect function in chat.js. Here's the function:
function _metaConnect(message) {
if (!$scope.joined) {
$scope.connected = false;
_connectionClosed();
} else {
var wasConnected = $scope.connected;
$scope.connected = message.successful === true;
if (!wasConnected && $scope.connected) {
_connectionEstablished();
} else if (wasConnected && !$scope.connected) {
_connectionBroken();
}
}
}
Specifically, what does the line
$scope.connected = message.successful === true;
accomplish?
$scope.connected gets the value of message.successful === true.
message.successful === true has the value true if message.successful has the value true or false if message.successful has any other value.

How can I create empty JSON keys (nested or not) using a string?

I currently have this code built in JS, but it's really, really ugly.
Is there any better way to approach it?
The way it works basically is pushing a string like app.chat.test to be the key, and value like teststr.
I test the lengths to see if the "parent" key is there, otherwise we build it.
function constructJson(jsonKey, jsonValue){
//REWRITE!!!!!!!!
let jsonObj = langFile;
let jsonKeyArr = jsonKey.split('.')
if (jsonKeyArr.length === 1) {
if (valToAdd === undefined) {
if (jsonObj[jsonKey] === undefined) {
jsonObj[jsonKey] = {}
}
} else {
if (jsonObj[jsonKey] === undefined) {
jsonObj[jsonKey] = valToAdd
}
}
} else if (jsonKeyArr.length === 2) {
if (jsonObj[jsonKeyArr[0]] === undefined) {
jsonObj[jsonKeyArr[0]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] = jsonValue
}
} else if (jsonKeyArr.length === 3) {
if (jsonObj[jsonKeyArr[0]] === undefined) {
jsonObj[jsonKeyArr[0]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]] = jsonValue
}
} else if (jsonKeyArr.length === 4) {
if (jsonObj[jsonKeyArr[0]] === undefined) {
jsonObj[jsonKeyArr[0]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]][jsonKeyArr[3]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]][jsonKeyArr[3]] = jsonValue
}
} else if (jsonKeyArr.length === 5) {
if (jsonObj[jsonKeyArr[0]] === undefined) {
jsonObj[jsonKeyArr[0]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]][jsonKeyArr[3]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]][jsonKeyArr[3]] = {}
}
if (jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]][jsonKeyArr[3]][jsonKeyArr[4]] === undefined) {
jsonObj[jsonKeyArr[0]][jsonKeyArr[1]][jsonKeyArr[2]][jsonKeyArr[3]][jsonKeyArr[4]] = jsonValue
}
} else if (jsonKeyArr.length > 5) {
return console.log("Length over 5 not supported yet!")
}
return jsonObj;
}
Regards.
OF course it's possible, a simple loop will perfeclty do the job.
function constructJson(jsonKey, jsonValue){
//REWRITE!!!!!!!!
langFile = {a:{}, foo:{}};// remove this for your own code
var jsonObj = langFile;
var jsonKeyArr = jsonKey.split('.');
var currentValue = jsonObj;
for(var i = 0; i < jsonKeyArr.length;i++){
if(currentValue[jsonKeyArr[i]]===undefined){
currentValue[jsonKeyArr[i]] = {};
}
if(i < jsonKeyArr.length-1){
currentValue = currentValue[jsonKeyArr[i]];
}else{
currentValue[jsonKeyArr[i]] = jsonValue;
}
}
return jsonObj;
}
alert(JSON.stringify(constructJson("a.b.cd.ef", "toto")));
I just assigning to a temporary variable each sublevel. When i'm on the last i'm assigning the value.
Yes you can, using the javascript reduce function on the array created from the splitted string.
function namespaceCreateExceptLast(representationOfElementToCreate, baseNamespace) {
var tokens;
if (typeof representationOfElementToCreate !== 'string')
throw new Error('Expecting string as first parameter');
if (baseNamespace === undefined)
baseNamespace = window;
tokens = representationOfElementToCreate.split('.');
// Remove the last element (which will contain the value)
tokens.pop();
// Use reduce to create part by part your new object
return tokens.reduce(function (prev, property) {
if (typeof prev !== 'object') {
throw Error('One property is already defined but not an object, namespace creation has failed', property);
return undefined;
} else {
if (!prev[property])
prev[property] = {};
return prev[property];
}
}, baseNamespace);
};
Then you can have:
function constructJson(jsonKey, jsonValue){
let jsonObj = langFile;
var lastItem = namespaceCreateExceptLast(jsonKey, jsonObj);
var lastKey = jsonKey.substring(jsonKey.lastIndexOf('.') + 1);
lastItem[lastKey] = jsonValue;
}
I have added some comments and exceptions to help you understand how it's done, but it's mainly based on the reduce function which you can easily get help for (https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array/reduce).

else if is not printing the console value

I have JavaScript code which displays a multi coffee value.
If I am trying to display a single value coffee, its not going inside the else if.
I modified existing code but getting an undefined error.
Can you tell me how to fix it?
var multCoffees = false;
var singleCoffee = false;
if (Coffees.length > 1) {
multCoffees = true;
}
if (Coffees.length > 1) {
singleCoffee = true;
}
if (apptTimeCell) {
apptTimeHTML = MyDay.dish(allData, multCoffees, singleCoffee);
apptTimeCell.innerHTML = apptTimeHTML;
} else {
apptTimeCell = Util.cep("span", {
className: "appt-time"
});
patientRowTD.insertBefore(apptTimeCell, patCell);
}
dish: function (allData, multCoffees, singleCoffee) {
if (multCoffees) {
var htmlArr = [];
htmlArr.push(allData.APPT_TIME_DISPLAY, "<br/><span class='sub-detail'>", allData.MNEMONIC, "</span>");
console.log("multiCoffee" + allData.PROVIDER_MNEMONIC);
return htmlArr.join("");
} else if (singleCoffee) {
console.log("inside if" + allData.PROVIDER_MNEMONIC);
var htmlArr = [];
htmlArr.push(allData.APPT_TIME_DISPLAY, "<br/><span class='sub-detail'>", allData.PROVIDER_MNEMONIC, "</span>");
console.log("singleCoffee" + allData.PROVIDER_MNEMONIC);
return htmlArr.join("");
} else {
return allData.APPT_TIME_DISPLAY;
}
},
Working code:
var multCoffees = false;
if (Coffees.length > 1) {
multCoffees = true;
}
if (apptTimeCell) {
apptTimeHTML = MyDay.dish(allData, multCoffees);
apptTimeCell.innerHTML = apptTimeHTML;
} else {
apptTimeCell = Util.cep("span", {
className: "appt-time"
});
patientRowTD.insertBefore(apptTimeCell, patCell);
}
dish: function (allData, multCoffees) {
if (multCoffees) {
var htmlArr = [];
htmlArr.push(allData.APPT_TIME_DISPLAY, "<br/><span class='sub-detail'>", allData.MNEMONIC, "</span>");
console.log("multiCoffee" + allData.PROVIDER_MNEMONIC);
return htmlArr.join("");
} else {
return allData.APPT_TIME_DISPLAY;
}
},
Suppose Coffees.length is 2. You do this...
if (Coffees.length > 1) {
multCoffees = true;
}
...and 2 > 1, so now multCoffees is true, but then you do this, which checks the same thing...
if (Coffees.length > 1) {
singleCoffee = true;
}
and, since 2 > 1 still, now BOTH multCoffees AND singleCoffee are true. So when you try to do
if (multCoffees) {
...
} else if (singleCoffee) {
...
}
the first if branch is true, so it is executed, and the else branch is thus ignored (despite also being true). You probably meant to instead start with
if (Coffees.length == 1) {
singleCoffee = true;
} else if (Coffees.length > 1) {
multCoffees = true;
}
replace your first two ifs with this block:
if (Coffees.length == 1) {
singleCoffee = true;
}
else if(Coffees.length > 1){
multCoffees = true;
}
and then try it again!

Categories