JS IOS issue: null is not an object - javascript

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.

Related

Javascript: for loop not working as expected

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

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/

Issue with jQuery data

I'm struggling a little. I'm attempting to utilize the cool feature of assigning a custom attribute to an element. However it isn't working.
Basically, I'm trying to assign multiple elements to the TR element identifying information in that row. Here is what it looks like:
for (x=0; x< theData.length; x++)
{
// create table row
var selector = "wc_" + wID + "_row_" + x;
oRow = document.createElement("TR");
oRow.setAttribute("id", selector);
tBodyO.appendChild(oRow);
var rowCount = 0;
var identCnt = 0;
for (var index in theData[x])
{
identCnt = 0;
if (hasIdentify)
{
for (y=0; y < theIdent.length; y++)
{
console.log("ROW: "+x+" , checking: "+index+" === "+theIdent[y]["data_name"]);
if (index === theIdent[y]["data_name"])
{
myrow = $("#" + selector);
//myrow.attr("test","works");
console.log("ident Dataname: "+theIdent[y]["data_name"]+ " identify:"+theIdent[y]["identify"]+" value: "+theData[x][index]);
jQuery.data( myrow, "test", { first: 16, last: "pizza!" });
alert(myrow.data("test"));
}
}
}
}
}
I've left out some code that's not really relevant, but I hope you get the picture. What I'm trying to do is this:
I have an array that contains "identity" information about a particular row of data. It can have 0, 1 or more such identity pieces. I want to store these as a custom data attribute on the <TR> element.
Each data will have a distinct key (example: i_0_1 where 0 is the data row number and 1 is the identity counter)
However, I can't get this to work. I've tried lots of alternatives even trying to resort to .attr() with no luck. What am I doing wrong??
I'm getting an alert that says undefined. When I try the myrow.attr("test","works"); route I can see the attribute in the DOM. Why won't the data() way work for me?
I just figured out what the problem is. I guess after reading the docs on jQuery.data() I didn't see anyone really clearly come out and say:
You will not see the data info in the DOM - element when you look at the source.
To the credit of everyone here, they did tell me, I just didn't know what I was reading (now that I know what is expected)
Matt wrote:
"ill not actually set an attribute or property on the element; jQuery stores this data in an internal cache, and merely maps it to the element you selected"
Although after playing around with the .attr() and setAttribute() functions I just became more confused.
Thanks everyone!

TypeError on val() called on li child

I use this code to order children from an ul. The select works fine but the value call in the error below. The li has a value.
for (var i = 0; i < $("#sortable").children("li").length; i++) {
sortedPlayerIds[i] = $("#sortable").children("li:nth-child(" + (i + 1) + ")").val();
}
I get this error:
TypeError: (c.value || "").replace is not a function
...d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test... jquery.min.js (linje 16)
I'm using:
1.8.16/jquery-ui.min.js
1.7.1/jquery.min.js
Any idea?
it's problem is in finding $(this) object in your loop, which one you get it with your counter, try this code:
$("#sortable li").each(function(){
var x = $(this).text();
};
The line of code given by you in error
d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test is present in jquery.min.js. Please Find(Ctrl+F) this line in this jquery file.
Right? Actually, it is not error related to jQuery. YOu are performing one jquery operation in wrong way. See where you have used function .replace in whole java script.

Validation for checkboxes

Hello
I have a JS function which says
for(var i = 0; i < document.calDailyBlock.selFilCheckBox.length; i++)
{
if(document.calDailyBlock.selFilCheckBox[i].checked)
{
filteredInitId += document.calDailyBlock.selFilCheckBox[i].value + ",";
alert(filteredInitId);
isProjCheck = true;
}
}
document.calDailyBlock.filteredComId.value = filteredInitId;
When there are no checkboxes on the page and I try to click on Filter button which calls this function, I receive an error "document.calDailyBlock.selFilCheckBox.length' is null or not an object"
Is there any simple thing which I can add in this function ?
Also can anyone help me how to check if there is only one checkbox on one page ?
Thanks in advance
I think you are relying on a fairly obscure (non-official) feature of some browsers which lets you get an element from the document as if it were an attribute. In other words, you are going:
document.calDailyBlock
This is searching the document for a variable calDailyBlock. Instead, you should use the standardised getElementById:
document.getElementById("calDailyBlock")
And use the same approach for getting selFilCheckBox.
This will return null if calDailyBlock or selFilCheckBox are not found. Before you go calling length on them (which gives that error), you should check to see if you got back null, and then (I suppose) fail silently (don't do anything).
to avoid the error use an if:
if(document.calDailyBlock.selFilCheckBox) {
for(var i = 0; i < document.calDailyBlock.selFilCheckBox.length; i++)
{ … }
}

Categories

Resources