Array.from returns empty array - javascript

I am trying to filter children of an div element.
I get direct access to the parent div via Angular ViewChild and if I print the children like this
console.log(this.myParentDiv.nativeElement.children);
I get the following output in Chrome:
I need to convert this to array to be able to filter the divs. However if I convert it like this
console.log(Array.from(this.myParentDiv.nativeElement.children));
It returns an empty array.
Any idea why it returns empty?

I think the problem in this case is that the Javascript code is being executed before the html document is ready.
Move your JS code or import to the bottom of the page and the problem should be fixed.

Not the fanciest solution but in order to achieve this I wrapped the logic into a timeout function:
setTimeout(() => {
const elementChildren = this.myParentDiv.nativeElement.children;
// regular for loop
for (let i = 0; i < elementChildren.length; i++) {
console.log(">>",elementChildren[i]);
}
}, 100);

Related

Using shift() brings back the first one every time (javascript)

I have a function that searches for every time ; is found inside a textarea and makes it into a array. See the code below.
function compile() {
// Sets the variable for every line
var compileLineCount = document.getElementById('devInput').value.split(';');
for (let i = 0; i < compileLineCount.length; i++) {
console.log(document.getElementById('devInput').value.split(';').shift(i))
console.log(i)
}
}
But whenever I call the function, it shows the first one every time.
Anyone know how to fix this? Help would be very appreciated.
As per the official shift() document.
The shift() method removes the first element from an array and returns that removed element. This method changes the length of the array.
Hence, It should be like :
var compileLineCount = document.getElementById('devInput').innerHTML.split(';');
for (let i = 0; i <= compileLineCount.length; i++) {
const splittedValue = compileLineCount.shift(i)
console.log(splittedValue)
console.log(i)
}
<p id="devInput">
Hello my name is alpha;Age is 30;I love to help
</p>
I figured out what I did wrong. I forgot shift() also removes the item from the array.
I changed it from .shift(i) to [i].
Thank you jsn00b for the link to the docs
Your shift() method is used incorrectly. According to MDN, it states:
The shift() method removes the first element from an array and returns that removed element.
So, the shift() method doesn't take any parameters. This is why your code isn't working.
To fix this issue, you can get the index from the array using [i], like so.
document.getElementById("devInput").value.split(";")[i];
The only difference in that line is that .shift() is replaced with [i], which gets the element in the array at that specific index.

How to add a class to all similar elements with an index less than the clicked element with jquery?

I have 8 elements in sequence that each represent a yoga pose. When one of these elements is clicked I want to add/remove classes for all the pose cards that come before and after the clicked element. So far I have been able to get the index of the clicked element using the following:
$(".pose-card").click(function () {
clickedPoseIndex = $(".pose-card").index(this);
});
And then I tried to use a filter function to get the ones whose index is less than the clicked one with something like this:
let prevPoses = $(".pose-card").filter(function () {
return parseInt($(".pose-card").index(this) < clickedPoseIndex);
});
But that did not work! Please let me know if you can think of any better solutions. Much appreciated!
What you want to do inside filter is get the index as int (hence the parseInt function) and compare with the value you've stored in clickedPoseIndex which is already an int. You've simply missed a bracket or misplaced one. All you have to do is:
let prevPoses = $(".pose-card").filter(function () {
return parseInt($(".pose-card").index(this)) < clickedPoseIndex;
});
Edit
Don't need to use parseInt either as the value returned is already an int so:
return $(".pose-card").index(this) < clickedPoseIndex;

Traversing elements in javaScript

I need to change the href of link in a box. I can only use native javaScript. Somehow I have problems traversing through the elements in order to match the correct <a> tag.
Since all the a tags inside this container are identical except for their href value, I need to use this value to get a match.
So far I have tried with this:
var box = document.getElementsByClassName('ic-Login-confirmation__content');
var terms = box.querySelectorAll('a');
if (typeof(box) != 'undefined' && box != null) {
for (var i = 0; i < terms.length; i++) {
if (terms[i].href.toLowerCase() == 'http://www.myweb.net/2/') {
terms[i].setAttribute('href', 'http://newlink.com');
}
}
}
However, I keep getting "Uncaught TypeError: box.querySelectorAll is not a function". What do I need to do in order to make this work?
Jsfiddle here.
The beauty of querySelectorAll is you dont need to traverse like that - just use
var terms = document.querySelectorAll('.ic-Login-confirmation__content a');
And then iterate those. Updated fiddle: https://jsfiddle.net/4y6k8g4g/2/
In fact, this whole thing can be much simpler
var terms = document.querySelectorAll('.ic-Login-confirmation__content a[href="http://www.myweb.net/2/"]');
if(terms.length){
terms[0].setAttribute('href', 'http://newlink.com');
}
Live example: https://jsfiddle.net/4y6k8g4g/4/
Try This:
var box = document.getElementsByClassName('ic-Login-confirmation__content')[0];
Since you are using getElementsByClassName ,it will return an array of elements.
The getElementsByClassName method returns returns a collection of all elements in the document with the specified class name, as a NodeList object.
You need to specify it as follows for this instance:
document.getElementsByClassName('ic-Login-confirmation__content')[0]
This will ensure that you are accessing the correct node in your HTML. If you console.log the box variable in your example you will see an array returned.
you can select by href attr with querySelector,
try this:
document.querySelector('a[href="http://www.myweb.net/2/"]')
instead of defining the exact href attribute you can simplify it even more :
document.querySelector('a[href?="myweb.net/2/"]'
matches only elments with href attribute that end with "myweb.net/2/"

Deleting an element from JSON in javascript/jquery

I have a problem in deleting data from a JSON object in javascript. I'm creating this JSON dynamically and the removal shall also take place dynamically. Below is my JSON and the situation I'm in to.
{brands:[51,2046,53,67,64]}
Now, I have to remove 53 from this which I am calculating using some elements property, but I'm not able to remove the data and unable to find the solution for this situation. Please help me folks, thank you.
Try to use Array.prototyp.splice,
var data = { brands:[51,2046,53,67,64] };
data.brands.splice(2,1);
Since you want to remove an element from an array inside of a simple object. And splice will return an array of removed elements.
If you do not know the position of the element going to be removed, then use .indexOf() to find the index of the dynamic element,
var elementTobeRemoved = 53;
var data = { brands:[51,2046,53,67,64] };
var target = data.brands;
target.splice(target.indexOf(elementTobeRemoved),1);
You could write the same thing as a function like below,
function removeItem(arr,element){
return arr.splice(arr.indexOf(element),1);
}
var data = { brands:[51,2046,53,67,64] };
var removed = removeItem(data.brands,53);

How to call jquery's .find in a lazy fashion?

When using jquery to locate a set of elements in an XML DOM structure;
Using .find with a CSS query will result in a result that can be iterated, however jquery will return all the results at that time, which is slow and pauses my UI.
How do I instead iterate over the results in a lazy fashion?
I observed that there is a .first() method, however I can't find .next() in the documentation, what am I missing?
Yes there is a next() and a prev() you can use to go to next or previous sibling in the DOM structure.
My best suggestion is to contain your searches. Never run global queries. If at all possible, start your search from an element that you can retrieve by ID (to limit the number of nodes to traverse)
For example instead of the following
var infoList = $("a.query span.info")
Use
var container = $('#myCt');
var infoList = container.find('a.query span.info');
// OR more simply (but I'm not sure jQuery optimizes the query)
var infoList = container.find('#myCt a.query span.info')
$(".class").each(function() {
//do code here
});

Categories