Javascript: for loop not working as expected - javascript

Im currently trying to set up a loop that returns exif data from an image using piexifjs.
Up to this point the code provided by the developer of piexif is working correct in my Vue.js environment.
The loop which is used to display the exif-data inside the console looks like this:
for (let ifd in exifObj) {
if (ifd == "thumbnail") {
continue;
}
console.log("-" + ifd);
for (let tag in exifObj[ifd]) {
console.log(" " + piexif.TAGS[ifd][tag]["name"] + ":" + exifObj[ifd][tag]);
}
}
Works fine, but if I try to edit it to return HTML and display the exif information on my Site it just returns one line of information. Here's the code:
for (let ifd in exifObj) {
if (ifd === "thumbnail") {
continue;
}
const exifInfo = $(".modal-exif"),
exifInfoDetail = $(".modal-exif-detail");
exifInfo.html("» " + ifd);
for (let tag in exifObj[ifd]) {
exifInfoDetail.html("<li>" + piexif.TAGS[ifd][tag]["name"] + ":" + exifObj[ifd][tag] + "</li>");
}
}
I guess my loop is overwriting itself where it returns just one value, which, I guess, is fine inside the console since but not inside HTML?
Anyone got any Idea hwo to change the loop to return one line for each entry?
Thank you :)

In the console.log case, each iteration is writing to the console, whereas in the $(selector).html() case, you are overwriting the html content per iteration. The jquery html function states:
Set the HTML contents of each element in the set of matched elements.
That means that each iteration, the html content of $(".modal-exif-detail") is set to one single "<li>" + piexif.TAGS[ifd][tag]["name"] + ":" + exifObj[ifd][tag] + "</li>".
You need to use something like append if you want to continually add to a node, or build up the html string and only execute one html after the loop

Related

Combine two variables into one input attribute JS

I have a input field
<input required id={'odds' + index} type="text" step="any" className="form-control validate" value={this.state.odds + ' ' + index} onChange={this.onChange} />
Where I'm trying to combine the value attribute
value={this.state.odds + ' ' + index}
value={this.state.odds + index}
value={this.state.odds`${index}`}
value={this.state.odds `${index}`}
I tried all these, but it didn't work. How do you combine a state and a index in an array map?
Expected result: this.state.odds0 where index is 0 and it calls the state element
Example of what I'm getting:
this.state.odds is set to 1.5
this.state.odds0 is set to 5
If index is 0 I get ' 1.5 0 ' or ' 1.50 ' with the commands over. I want to get ' 5 '.
You are not getting the desired result because this.state.odds returns a number and you are trying to join it with another number by string concatenation but that will just give you a string. It won't get the value you want from the state
To get the required value from the state, try
value={this.state['odds' + index]}
You are using the wrong approach, you can't put JavaScript code on the value attribute directly on the HTML, instead you should change it from a script tag.
Let me give you an example:
We first create our input element on or HTML, note the id atrribute, it should be unique across all elements of your HTML document or it will not work properly.
<input id="changeThisToYourUniqueID">
Then we create another element, the script element, this is where we will manipulate our code.
<script></script>
We write the javascript code inside the script element, setting the value of the object to be the sum of the constant and the index.
<script>
let timesWeWantToLoop = 3
for(let index = 0; index < timesWeWantToLoop; index++){
document.getElementById("changeThisToYourUniqueID").value = "holamigos!"+index;
}
</script>
The change will happen very fast, so if you really need to see the change happening you can use a recursive function adding a delay to it with the native JavaScript setTimeout() function.
<input id="changeThisToYourUniqueID">
<script>
let index = 0;
let timesWeWantToLoop = 3
function myLoop() {
document.getElementById("changeThisToYourUniqueID").value = "holamigos!"+index;
setTimeout(function() {
index++;
if (index < timesWeWantToLoop) {
myLoop();
}
}, 1000)
}
myLoop()
</script>
Note: The example will not work under variable input situations, on those cases you need to create an event listener to see when the input value changes.
Cheers!

JS IOS issue: null is not an object

I have two arrays:
var tableIdsSold = [3, 38, 43, 44];
var tableIdsBook = [40];
I receive array elements from backend, right after "body" tag opens.
Then, before "body" tags closes, i put link to "main.js".
In "main.js" i have this code runnin:
for (var i = 0; i < tableIdsSold.length; i++) {
document.querySelector('[data-circleId="' + tableIdsSold[i] + '"]').classList.add('purchased');
}
and same for second array.
So i just run through array, use array element as id. When script finds element with right id - it should add class to html tag "circle".
So the problem is: script works everywhere, but not in IOS. If i open this page in mac (safari/chrome) or iphone 5/6 (safari/chrome), i get this error in console:
TypeError: null is not an object (evaluating 'document.querySelector('[data-circleId="' + tableIdsSold[i] + '"]').classList')
Script runs in "window.onload" function. What's causing the problem?
Sorry for bad english
The Document method querySelector() returns the first Element within the document that matches the specified selector, or group of selectors. If no matches are found, null is returned.
You need to check if this document.querySelector('[data-circleId="' + tableIdsSold[i] + '"]') null then no need to do action.
CODE SNIPPET
for (var i = 0; i < tableIdsSold.length; i++) {
let circleId = document.querySelector('[data-circleId="' + tableIdsSold[i] + '"]');
if (circleId) {
circleId.classList.add('purchased');
}
}
So the problem was: somehow ios html interpretator writes "data-circleId" class as "data-circleid". My JS script couldn't find "data-circleId" because of this.

Printing elements of an array

I'm trying to print the elements of an array. When I try a very basic W3 Schools Example, it works perfectly, but when I take the loops and variables and modify it to my application, it's acting oddly.
Basically, I have a user input. That input is pushed into an empty array. I'm using a loop to cycle through that array and print each element to the screen. If you see the pic, it's not printing correctly. I've tried three different versions of loops and all aren't printing the way I expect.
I instantiate the charNotInWordArr out of the function.
var charNotInWordArr = [];
Relevant JS:
charNotInWordArr.push(userInput);
console.log("the char is not in the word");
console.log("the char is " + userInput)
for (var i = 0; i < charNotInWordArr.length; i++) {
$('#wrongGuessList').append("<li class='list-group-item'>" + userInput[i] + "</li>");
}
Other for loops gone wrong:
$.each(charNotInWordArr, function(userInput) {
$('#wrongGuessList').append("<li class='list-group-item'>" + userInput[i] + "</li>");
});
$.each(charNotInWordArr, function(index, value) {
$('#wrongGuessList').append("<li class='list-group-item'>" + value[i] + "</li>");
});
It's printing like this:

Make object Object as index of array (Javascript)

I've been using a crossword app from this repo: https://github.com/jweisbeck/Crossword . The problem is that the program uses jquery version 1.6.2 and my whole project uses jquery-3.1.1 version. Particularly, the error arises here:
buildEntries: function() {
var puzzCells = $('#puzzle td'),
light,
$groupedLights,
hasOffset = false,
positionOffset = entryCount - puzz.data[puzz.data.length-1].position; // diff. between total ENTRIES and highest POSITIONS
for (var x=1, p = entryCount; x <= p; ++x) {
var letters = puzz.data[x-1].answer.split('');
for (var i=0; i < entries[x-1].length; ++i) {
light = $(puzzCells +'[data-coords="' + entries[x-1][i] + '"]');
if($(light).empty()){
console.log($(light));
$(light)
.addClass('entry-' + (x-1) + ' position-' + (x-1) )
.append('<input maxlength="1" val="" type="text" tabindex="-1" />');
}
}
}
// Put entry number in first 'light' of each entry, skipping it if already present
console.log(entries);
console.log(puzz.data);
for (var i = 0; i < entryCount; i++) {
$groupedLights = $('.entry-' + i); 
if(!$('.entry-' + i +':eq(0) span').length){
$groupedLights.eq(0)
.append('<span>' + puzz.data[i].position + '</span>');
}
}
util.highlightEntry();
util.highlightClue();
$('.active').eq(0).focus();
$('.active').eq(0).select();
}
The error arises at line with
light = $(puzzCells +'[data-coords="' + entries[x-1][i] + '"]');
The browser shows this error:
Error: Syntax error, unrecognized expression [object Object][data-coords="1,6"]
I believe this is related to the jQuery version. Or maybe the program uses [object Object] as index. Not sure as I am new in jQuery. I tried to use jQuery Migrate, but it didn't help. Also, I tried to use that jQuery 1.6.2, but a web browser could not find jQuery at all as I am using Typescript and had to install jQuery through .d.ts file. Any tips or advises? Thanks in advance
As the title says:
Make object Object as index of array
That is not possible with standard Objects/Arrays, but you can use a Map for that:
let map = new Map(),
key = {id: '##'};
map.set(key, [1,2,3,4,5]);
console.log(map.get(key)); //[1,2,3,4,5]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
The [object Object] in the string shown in the error is because a jQuery object is being appended to a string to create a selector, which is invalid.
In your code, it's this line causing the problem:
var puzzCells = $('#puzzle td') // holds jQuery object
// later on...
light = $(puzzCells + '[data-coords="' + entries[x-1][i] + '"]');
This is nothing to do with the version of jQuery being used as it's a syntax issue.
To fix this you should use filter() on the puzzCells object, instead of appending it to a selector. Try this:
light = puzzCells.filter('[data-coords="' + entries[x-1][i] + '"]');
You are concatenating an object (puzzCells) and a string. When JavaScript detects an string concatenation tries to convert all the variables to strings before concatenating them. In plain JavaScript, if you do WHATEVEROBJECT.toString() you will receive [object Object], that's why you see an error containing that message.
This is not jQuery version problem, as this happens at the very low level (JavaScript).
puzzCells is a jQuery object, where you can call jQuery methods. In this case you need the filter method, like this:
light = puzzCells.filter('[data-coords="' + entries[x-1][i] + '"]');
Check out more info right here: http://api.jquery.com/filter/

JavaScript not recognizing variable

I'm new to Javascript and struggling to figure out why this piece of code isn't working for me.
Essentially I'm defining a variable, yet when I go to use that variable in an IF or Switch statement, it doesn't seem to be able to match the contents of the variable. No errors, the IF statement just doesn't get satisfied. While with the Switch, it always falls through to the default setting, as it can't match the contents.
I have a Print statement in place after the variable is defined, and it does display the contents of the variable correctly.
I'm really at a loss as to why the print can return the value of the variable, yet the IF and Switch can't find it.
Below is the snippet I'm working from. The variable is "strWilma", which doesn't get reflected properly in the Print second value statement, but not in the IF.
for (var i=0; i < Flinstones.length; i++)
{
if (Flinstones[i].startsWith("?"))
{
// Convert the Secondary field map to a Properties item, for easier navigation
var objSecondaryFieldMap = PropertiesFromString(strSecondaryFieldMap);
// Map all of the Secondary values
var arraySecondaryFields = objSecondaryFieldMap.keys();
while (arraySecondaryFields.hasMoreElements())
{
strFred = arraySecondaryFields.nextElement();
strWilma = objSecondaryFieldMap.get(strFred);
print("TargetType:" + Object.prototype.toString.call(strFred));
print("SourceType:" + Object.prototype.toString.call(strWilma));
print("Text Type:" + Object.prototype.toString.call("hardcoded value"));
print("First Value:" + objItem.getNewFieldValue(Flinstones[i].substring(1)) );
print("Second Value:" + strWilma );
if (objItem.getNewFieldValue(Flinstones[i].substring(1)) == strWilma)
//if (objItem.getNewFieldValue(Flinstones[i].substring(1)) == "hardcoded value") // WORKS
{
print("It Worked!!!");
}
}
}
}
}
Thanks

Categories

Resources