Reputation:
I have an array containing a list of cars, and an image URL.
On the page, i have a list of lots of cars. I want to loop over all cars on page, and if it is within the cars array, then I want to swap it's image to the new one.
What would be the best way to go about this?
<!-- example of on page list of cars -->
<li class="car" data-id="car1">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car12">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car2">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car7">
<img src="https://imageurl.com/currentImage" alt="">
</li>
--
const cars = [
{
"id": "car1"
"newImage": "imageaddress1"
},
{
"id": "car2"
"newImage": "imageaddress2"
},
{
"id": "car3"
"newImage": "imageaddress3"
},
]
const allCarsNodeList = document.querySelectorAll('.car');
const allCars = Array.from(allProductsNodeList);
First thoughts are to use filter to reduce the on page cars down to only the ones featured, but I'm lost on how to do the comparison since in neither the array or the on page data-attribute are directly there.
I'm confused basically! Any points in the right direction would be greatly appreciated.
Upvotes: 1
Views: 78
Reputation: 582
Since your cars are stored in an array with a unique id, I would recommend converting this cars array into a dictionary first (this will increase performance):
const cars = [
{
"id": "car1",
"newImage": "imageaddress1"
},
{
"id": "car2",
"newImage": "imageaddress2"
},
{
"id": "car3",
"newImage": "imageaddress3"
}
]
// create cars dictionary from carsList
const carsDictionary = cars.reduce((r, car) => {
r[car.id] = car;
return r;
}, {});
// iterate over nodes with car class
const carNodesDict = Array.from(document.querySelectorAll('.car'))
.forEach((node) => {
const car = carsDictionary[node.dataset.id];
if (car != null) {
node.querySelector('img').src = car.newImage;
}
});
<!-- example of on page list of cars -->
<li class="car" data-id="car1">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car12">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car2">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car7">
<img src="https://imageurl.com/currentImage" alt="">
</li>
Upvotes: 0
Reputation: 28445
You can try following
cars
array with id
as key and image url as valuesrc
of corresponding img
const cars = [{"id": "car1","newImage": "imageaddress1"},{"id": "car2","newImage": "imageaddress2"},{"id": "car3","newImage": "imageaddress3"}];
// Create a map of id and newImage
const obj = cars.reduce((a,c) => Object.assign(a, {[c.id] : c.newImage}), {});
// Get all cars
const allCars = Array.from(document.querySelectorAll('.car'));
// Iterate over cars
allCars.forEach(c => {
//if entry exists in the object, update corresponding image
if(obj[c.dataset.id]) c.querySelector("img").src = obj[c.dataset.id];
});
<li class="car" data-id="car1">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car12">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car2">
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car7">
<img src="https://imageurl.com/currentImage" alt="">
</li>
Upvotes: 1
Reputation: 15499
Iterate over the results in the node list and compare the data-id to the id of the cars array. If it matches - swap the src attribute to the newImage.
I am also updating the alt attribute so that you can see the src has changes (since I don't have your images)
const cars = [
{
"id": "car1",
"newImage": "imageaddress1"
},
{
"id": "car2",
"newImage": "imageaddress2"
},
{
"id": "car3",
"newImage": "imageaddress3"
},
]
const allCarsNodeList = document.querySelectorAll('.car');
allCarsNodeList.forEach(function(car, index){
var id = car.getAttribute('data-id');
var image = car.querySelector('img');
cars.forEach(function(carItem){
if(carItem.id == id) {
image.setAttribute('src', carItem.newImage);
image.setAttribute('alt', carItem.newImage) ;
}
})
})
<ul>
<li class="car" data-id="car1">
<img src="https://imageurl.com/currentImage" alt="currentImage">
</li>
<li class="car" data-id="car12">
<img src="https://imageurl.com/currentImage" alt="currentImage">
</li>
<li class="car" data-id="car2">
<img src="https://imageurl.com/currentImage" alt="currentImage">
</li>
<li class="car" data-id="car7">
<img src="https://imageurl.com/currentImage" alt="currentImage">
</li>
</ul>
Upvotes: 0
Reputation: 150
This work for me :
const allCarsNodeList = document.querySelectorAll('.car');
const allCars = Array.from(allCarsNodeList);
console.log(allCars)
allCars.forEach(car => {
carId = car.dataset.id
correspondingCar = cars.filter(each => each.id === carId)[0]
console.log(correspondingCar);
if (correspondingCar !== undefined) {
car.children[0].src = correspondingCar.newImage
}
})
Upvotes: 0
Reputation: 30739
You need to follow these steps:
car
data-id
value of each elementdata-id
value to find a matching object in cars
arraysrc
attribute of that image which is inside the .car
element with the newImage
value of the object.const cars = [{
"id": "car1",
"newImage": "imageaddress1"
},
{
"id": "car2",
"newImage": "imageaddress2"
},
{
"id": "car3",
"newImage": "imageaddress3"
}
]
const allCarsNodeList = document.querySelectorAll('.car');
for (var i = 0; i < allCarsNodeList.length; i++) {
var carId = allCarsNodeList[i].dataset.id;
var matchCar = cars.find(({id}) => carId === id);
if (matchCar) {
allCarsNodeList[i].querySelector('img').src = matchCar.newImage;
}
}
<li class="car" data-id="car1">1
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car12">2
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car2">3
<img src="https://imageurl.com/currentImage" alt="">
</li>
<li class="car" data-id="car7">4
<img src="https://imageurl.com/currentImage" alt="">
</li>
Use
inspect element
on the output to check that thesrc
attribute is actually changed by the value of thenewImage
Upvotes: 0