Get first value if there is a match - javascript

Ok, so I have a simple variable declaration with a match regex query.
var image = decl.val.match(/(url\(.*\))/)[1];
But I found out quickly I cannot do this because sometimes there is no match and instead of returning undefined or something like that an error comes up:
Uncaught TypeError: Cannot read property '1' of null
I would like to fix this as inline as possible as I will have to iterate this many times throughout my code. Thanks for the help!

Rather than trying to find magic 1 line solution you can do:
var m = decl.val.match(/url\(.*\)/);
var image = m ? m[0] : "";

Shortest one-liner you can probably get is
var image = decl.val.match(/(url\(.*\))/)); image = image ? image[1] : ""
(Or whatever your preferred alternative to "" is.)
Oh well, come to think of it, you can still go a little further with
var image = (image = decl.val.match(/(url\(.*\))/)) ? image[1] : "";
if that looks better to you …
This works due to the fact that variables are “hoisted” in JavaScript – that means first the code is searched for all variable declarations (var image in this case) and those variables are created, and the actual code is executed only after that.

Related

Passing PHP array to JAVASCRIPT (issue)

There's some weird issue it seems.
I'm trying to pass a php array to js, which I've accomplished. I can display the array size like so
document.getElementById("test").innerHTML = (jarr.length);
and it works perfectly fine, however, when I try to display a value in said array, it says object Object
and what's weird is if I go try to read a value which isnt stored, for example jarr[234] it says undefined because there's no value stored, so I know some data is being transferred.
Any help?
edit: here's how I passed the array to js
var jarr = <?php echo json_encode($testing); ?>;
edit: I forgot the remove the parse part before copying it, I was experimenting beforehand.
You should be able to just directly use jarr without parsing it, for example:
document.getElementById("test").innerHTML = jarr.length;
document.getElementById("first_element").innerHTML = jarr.length > 0 ? jarr[0] : "empty array";
If you are doing the above and the elements are showing up as object Object it means that inside your array, you are storing objects rather than primitive data types. So maybe try something like the following to generate a nice string representation of those objects (noting that this is needed for displaying them, but not for using them directly in your JavaScript code):
document.getElementById("first_element").innerHTML = jarr.length > 0 ? JSON.stringify(jarr[0]) : "empty array";
What Chris said fixed the issue!
"To show the entire array: document.getElementById("test").innerHTML = JSON.stringify(jarr); To show a single string: document.getElementById("test").innerHTML = jarr[0]; – Chris G 7 mins ago
"
For whatever reason adding the (stringify) fixes it for me.
An example
document.getElementById("test").innerHTML = JSON.stringify(jarr[2].title);

Concatenating a value onto the end of an object property?

I'm saving user preferences using localStorage, like this:
choicesObject = { //put values in an object
"measure1" : $("#m1").is(':checked'),
"measure2" : $("#m2").is(':checked'),
"measure3" : $("#m3").is(':checked'),
"measure4" : $("#m4").is(':checked'),
"measure5" : $("#m5").is(':checked'),
"measure6" : $("#m6").is(':checked'),
"measure7" : $("#m7").is(':checked'),
"measure8" : $("#m8").is(':checked')
}
localStorage.setItem("choices", JSON.stringify(choicesObject));
Then I'm getting them back out like this:
retrieveChoices = localStorage.getItem("choices");
choicesObject = JSON.parse(retrieveChoices);
for(var i = 0;i<9 ;i++){
This nex t line is the problem:
ticked = choicesObject.measure+i;
It just doesn't work and I've tried using quotes and square brackets.
element = "#m" + i;
if(ticked==true){
$(element).prop('checked', true);
}
else{
$(element).prop('checked', false);
}
}
}
I want to loop though the measure properties and restore the checkbox elements.
I'm aware that even my object create is inefficient and I could use a for loop for that but I just don't know how to deal with object properties when it comes to looping because I don't get how you can do it without breaking the object.
At least that works and I can get data into and out of objects that get stored in localStorage, but this really simple issue has me stumped.
PS. Would
choicesObject = localStorage.getItem(JSON.parse("choices"));
be a better shorthand? Just thought this now whilst re-reading my question.
Edit: Thanks everyone. I got 3 correct answers so quickly! Amazing. Thanks so much. This site and its members amaze me every day and have revolutionised my coding!
I'm going to choose the correct answer as the one that also gave me the new shorthand for my parsing, but all of you gave me what i needed to know. I'm going to go see if I can answer some noob questions now!
Use
ticked = choicesObject["measure"+i];
EDIT: Your shorthand would not work, use instead:
choicesObject = JSON.parse(localStorage.getItem("choices"));
An object is just like a "dictionary" of values, so you can access a property either by doing myobject.propertyName or myobject["propertyname"]. They are equivalent.
In your case you just have to replace ticked = choicesObject.measure+i; with
ticked = choicesObject["measure"+i];
Also, consider using the var keyword when defining variables, each time you ommit it a new global variable will be created in the window object, that is the case for retrievedChoices and choicesObject. You can confirm this by accessing them via window["choicesObject"] or window.choicesObject or just choicesObject anywhere after that script has run.

syntax error in GAS script editor

I have an error in the following code and I can't find why...
Using UiApp I define a couple of ListBox like this in a for loop
var critGlist = app.createListBox().setName('critGlist'+n).setId('critGlist'+n).addChangeHandler(refreshGHandler).addChangeHandler(cHandlerG).setTag(listItem[n]);
I added a TAG to be able to retrieve a value in the handler function because when I add items to this list I do it like this :
for(var c=0;c<listItem[n].length;++c){
critGlist.addItem(listItem[n][c],c);// the returned value is c, the value shown is listItem[n][c]
}
Then in my handler function I retrieve the value c that is the index of an element of the array listItem[n]
Since I stored a stringified value of this array as a tag I have to retrieve the tag first and then using the index I get the desired value...
That's where it becomes problematic !
I tried the 3 following codes :
var idx = Number(e.parameter['critGlist'+c]);// this works and I get the index
var item = e.parameter.critGlist0_tag.split(',')[idx];// this also works for a fixed index (0 here) but I need to use it in a for loop so I tried the code below
var item = e.parameter['critGlist'+c]_tag.split(',')[idx];// this generates an syntax error
// error message :"Signe ; manquant avant l'instruction. (ligne 129, fichier "calculatrice Global")"
// which means : missing ; before statement (line 129...
Am I missing something obvious ? How should I write it differently ?
Obviously it is the underscore that is not accepted... but how could I not use it ?
Well, I have a few other possibilities to get the result I want (using a hidden widget for example or some other temporary storage of even let the listBox return the value instead of the index) but still I'd like to know why this syntax is wrong ...
I'm not asking for a different code (as mentioned before there are a lot of other ways to go) , just some explanation about what is wrong in this code and this #!##å»ÛÁØ underscore ;)
You will need to put the whole property within the brackets as below
var item = e.parameter['critGlist'+c+'_tag'].split(',')[idx];// this generates an syntax error

Displaying images with Javascript based on user input

I have been trying to display image with the following code. The user input is intended to be compared to bring up the right picture.
$(document).ready(function(){
var defaultimg = document.getElementById('image1');
defaultimg.src = pictureImage;
var pictureImage = "images/unknown.png";
if({{messages.get.message}} == "Mewtwo"){
var imgobject = document.getElementById('image1');
imgobject.src = pictureImage;
pictureImage = "images/150.png";
}
if({{messages.get.message}} == "Charmeleon"){
var imgobject2 = document.getElementById('image1');
imgobject2.src = pictureImage;
pictureImage = "images/005.png";
}
if({{messages.get.message}} == "Warturtle"){
var imgobject3 = document.getElementById('image1');
imgobject3.src = pictureImage;
pictureImage = "images/008.png";
}
)}
to the following piece of html
<img id="image1" alt="Pokemon" width="88" height="75"> 
At the moment it only displays an empty box.
Can someone offer advice on whether this approach can be fixed to display the images? Thanks for the time and help.
that's probably a reference loop:
$(document).ready(function(){
var defaultimg = document.getElementById('image1');
// defaultimg now contains image1
// using jQuery and getElementbyId together is weired
defaultimg.src = pictureImage;
// pictureImage is not assigned, so the url is empty
// prob. cause for empty block?
var pictureImage = "images/unknown.png";
// ok, now we assign an url
if({{messages.get.message}} == "Mewtwo"){
// is that path correct?
var imgobject = document.getElementById('image1');
// copy of the empty image from above
imgobject.src = pictureImage;
// we assign an url
pictureImage = "images/150.png";
// new url on pictureImage, unused so far.
}
...
if none of the conditions like if({{messages.get.message}} == "Mewtwo"){
is true, it must show nothing due to defaultimg.src = pictureImage; with unassigned pictureImage variable.
You might want to state with which kind of template engine or the like you work, as "{{messages.get.message}}" wouldn't help you much in vanilla js (though it would be syntactically well formed)
Tip for debugging:
debugger;
in js code starts up the debugger in chrome/firefox(+firebug)/...
otherwise you can also use the console commands, e.g.
console.debug("if 1")
to find out what is happening
also have a look at console output in general, there should be no warnings or errors.
Next:
You're trying to use the probably global (because of missing "var" in front) variable "pictureImage" before you define it. Javascript is run from start to end, from left to right (let's just assume it's that way for easier understanding), top to bottom.
So you try to set the src of an image to something which is undefined at that point, and later on define that variable. There is no such thing as pointers to non-object types in javascript (which string constants are)
To fix your problem you'll probably have to swap some lines in your code, so the used variable gets set, and THEN is used, not the other way around.

parseInt not working for window.document

Is there a reason that this would not work?
var xcurrent = parseInt(window.document.getElementById('firstdiv').style.left);
var ycurrent = parseInt(window.document.getElementById('firstdiv').style.top);
I'm being told it's not an integer NaN.
u̶ ̶n̶e̶e̶d̶ ̶t̶o̶ ̶r̶e̶m̶o̶v̶e̶ ̶̶p̶x̶̶ ̶f̶r̶o̶m̶ ̶t̶h̶e̶ ̶s̶t̶r̶i̶n̶g̶ ̶ (doesn't matter on modern browsers)
make sure window.document.getElementById('firstdiv').style.left is defined. you can't access this property if it's defined only in CSS
Examples:
CSS: http://jsfiddle.net/zuKYr/
Inline: http://jsfiddle.net/zuKYr/1/
JS: http://jsfiddle.net/zuKYr/2/
only style defined by JS and inline CSS is readable by JS.
It's not parseInt that isn't working, NaN suggests that the element you are trying to reference cannot be interpreted as an integer. Although it is difficult to say for certain, make sure that the elements you are referencing actually exist and see if you can access them at all before manipulating them. i.e check that window.document.getElementById('firstdiv') gives you anything before trying to do any more with it.
You also need to make sure that your css has actually set the attribute you are trying to retrieve otherwise you will get an undefined/Nan error.
If you're trying to get the x and y position of an element, you can use offsetLeft and offsetTop instead.
var firstDiv = document.getElementById('firstdiv');
var xcurrent = firstDiv.offsetLeft;
var ycurrent = firstDiv.offsetTop;
This will get the x and y position (with respect to the offsetParent) whether they were set through CSS positioning or not.
Is there a reason that this would not work?
var xcurrent = parseInt(window.document.getElementById('firstdiv').style.left);
Quite a few, but the likely ones are:
If element with id 'firstdiv' doesn't exist, window.document.getElementById('firstdiv') will return null. Attempting to access the style property of null will throw an error. That's not the result you specified though.
The value returned by .style.left is an empty string. In that case, parseInt returns NaN per ECMA-262.
A safer approach is:
var el = document.getElementById('firstdiv');
var xcurrent
if (el) {
xcurrent = parseInt(el.style.left);
if (isNaN(xcurrent)) {
// there was no value for xcurrent, what now?
As Nathan said, you can use offsetLeft instead.

Categories

Resources