I am a beginner in JavaScript and I can't figure out the following problem: I am trying to create a simple JavaScript Movie List. I have 10 lists on the Movie List. I tried to show all of the lists with for loop, but it doesn't work. Here's the code:
function renderModal() {
for (let i = 0; i < listMovies.length; i ) {
let movieData = listMovies[i];
document.getElementById("poster").src = movieData.img;
document.getElementById("title").innerHTML = movieData.name;
document.getElementById("genre").innerHTML = movieData.genre;
document.getElementById("rating-num").innerHTML = "Rating: " movieData.rating "/10";
document.getElementById("movie-desc").innerHTML = movieData.desc;
document.getElementById("imdb-page").href = movieData.link;
return movieData;
}
}
What do I have to do? Help me to fix it!.
CodePudding user response:
Your return movieData;
will stop the loop dead. Not that running it more than once will change anything since you change the same elements over and over. IDs must be unique.
Here is a useful way to render an array
document.getElementById("container").innerHTML = listMovies.map(movieData => `<img src="${movieData.img}" />
<h3>${movieData.name}</h3>
<p>${movieData.genre}</p>
<p>Rating: ${movieData.rating}/10</p>
<p>${movieData.desc}
<a href="${movieData.link}">IMDB</a>
</p>`).join("<hr/>");
CodePudding user response:
With return movieData, the for loop will ends in advance.You should put it outside the for loop.
CodePudding user response:
The problem in your code is that you are generating a general setActive state that is then passed to all your item in your map function. You have to change your state management in order to be able to find for each of the item if they are active or not. I'd rework a bit your component:
const Accordion = (props) => {
const [activeIndex, setActiveIndex] = useState(0);
const content = useRef(null);
return (
<div>
{data.map((item, index) => {
const isActive = index === activeIndex
return (
<div key={index} className="accordion__section">
<button
className={`accordion ${isActive ? "active" : ""}`}
onClick={() => setActiveIndex(index)}>
<p className="accordion__title">{item.title}</p>
<Chevron className={`${isActive ? "accordion__icon" : "accordion__icon rotate" }`} width={10} fill={"#777"} />
</button>
<div
ref={content}
style={{ maxHeight: `${isActive ? "0px" : `${content.current.scrollHeight}px`}` }}
className="accordion__content">
<div>{item.content}</div>
</div>
</div>
)})}
</div>
);
};
The idea is that for each item in loop you find which on is active and then assign the classes / styles according to this. Could be even more refactored but I let you clean up now that the idea should be there :)
CodePudding user response:
You can use template tag for list and render it into target element.I am showing an example.
Movie list
<div id="movieList"></div>
template for list
<template id="movieListTemplate">
<div class="movie">
<img src="" class="poster" alt="">
<div class="title"></div>
<div class="genre"></div>
<div class="rating-num"></div>
<div class="movie-desc"></div>
<div class="imdb-page"></div>
</div>
</template>
Javascript code:
if (listMovies.length > 0) {
const movileListTemplate = document.getElementById('movieListTemplate')
const movieRenederElement = document.getElementById('movieList')
for(const movie of listMovies) {
const movieEl = document.importNode(movileListTemplate.content, true)
movieEl.querySelector('.poster').src = movie.img
movieEl.querySelector('.title').textContent = movie.name
//use all queryselector like above
}
}
CodePudding user response:
listMovies.forEach(renderModal)
function renderModal(movie, index, arr) {
let movieData = movie;enter code here
}