Home > Software design >  class recovery problem generated by do while loop by event
class recovery problem generated by do while loop by event

Time:06-03

I would like to retrieve the class when I click on the link that contains -> in the viewPoster function. I don't know if it's because of the html() function or the event that prevents me from retrieving the name of the class from the DOM when I click on

template  = '<a href="#" id="prez_jaquetteDiv" ><p >'   data[i].title   '</p><img src="'   condJaq   '"  /></a>';
    $("#prez_choiseJaq").html(template);

I tried to put onclick in the template variable:

template  = '<a href="#" onclick="test()" id="prez_jaquetteDiv" ><p >'   data[i].title   '</p><img src="'   condJaq   '"  /></a>';
    $("#prez_choiseJaq").html(template);

I have an error! when on one of the posters displays

File HTML

<div id="prez_rech" >
                <label for="fname">Recherche du film :</label>
                <input type="text" placeholder="Entrez votre film ici" id="prez_input">
                <xf:button type="button" id="prez_btn">Rechercher</xf:button>
            </div>

            <div id="prez_choiseJaq"></div>
    <footer ><a href="https://xenfrench.net">Created by Marilyn</a></footer>

    <script type="module" src="js/vendor/prez/prez.js"></script>

File getValue .js

import { array } from './params.js';

const key = array['key'];
const urlMovie = array['urlMovie'];
const noCover = array['noCover'];
const urlImg = array['urlImg'];
const urlJaq = array['urlJaq'];
var jaq = document.getElementById("prez_choiseJaq");
var input = document.getElementById("prez_input");
var myBtn = document.getElementById("prez_btn");
var rech = document.getElementById("prez_rech");
var jaqSelected = $("a.prez_col-"   i);
var data = [];
var inputRep;
var urlNoCover = urlImg   noCover;
var url = urlMovie   key;
var i;
var test = false;

input.addEventListener("keypress", function (event) {
    if (event.key === "Enter") {
        event.preventDefault();
        inputRep = input.value;
        getValue();
    }
});

myBtn.addEventListener("click", event => {
    event.preventDefault();
    inputRep = input.value;
    getValue();
});


jaqSelected.click(function() {
    alert(jaqSelected);
});


async function getValue() {
    console.log(inputRep);
    try {
        const response = await fetch(url   "&language=fr-FR&query="   inputRep   "&page=1&include_adult=false");
        const responseData = await response.json();
        data = responseData?.results;
        console.log(data);
        if (!data.length) {
            alert("Le film que vous demandez n'est pas disponible !");
        } else {
            viewPoster();
        }
    } catch (error) {
        console.log(error);
    }
    return data;
};

function viewPoster() {
    test = false;
    if (data) {
        var template = "";
        jaq.style.display = "inline-grid";
        i = -1;
        do {
            i  = 1;
            console.log(i);
            let condJaq;
            if (data[i].poster_path == null) {
                condJaq = urlNoCover;
            } else {
                condJaq = urlJaq   data[i].poster_path;
            };
            template  = '<a href="#" id="prez_jaquetteDiv" ><p >'   data[i].title   '</p><img src="'   condJaq   '"  /></a>';
            $("#prez_choiseJaq").html(template);
        } while (i < data.length);
    };
};

function selected(arg) {
    console.log(arg);
};

export { getValue };

File params.js

var array = {
    key: "exemple",
    urlMovie: 'https://api.themoviedb.org/3/search/movie?api_key=',
    urlSerie: 'https://api.themoviedb.org/3/search/tv?api_key=',
    urlImg: 'styles/prez/img/',
    urlJaq: "https://image.tmdb.org/t/p/w154",
    noCover: "no_cover.jpeg",
};

export { array };

File prez.js

import { array } from './params.js';
import { getValue } from './getValue.js';

do you have an idea ?

Thanks in advance.

CodePudding user response:

Your do {} while () loop condition is trying to loop one beyond your data array. The problem is how you set up and increment your iterator variable: i.

You set your iterator to i = -1; before the loop, then, first thing in the loop you increment it: i = 1;, and the while condition is set to stop looping when i is equal to the array length: while ( i < data.length ). If an array has one element, i must be value 1 to discontinue the loop. At the end of the first pass i is equal to 0. Even in the case of a single array element it is still less than the length of the array so the loop will loop again. One element, two loops. Two elements, three loops. Three elements, four loops, etc.

The simple fix is change:

while (i < data.length);

...to:

while (i < data.length - 1);

Regardless of what type of loop you use: for, while, do while, it makes more sense to me to use your loop iterator, when you need one, as such:

let ii = 0;
do {
    doStuff(data[ii]);
    ii  ;
} while ( ii < data.length );

Here's the function (simple fixed) where you're do {} while () loop is:

function viewPoster() {
    test = false;
    if (data) {
        var template = "";
        jaq.style.display = "inline-grid";
        i = -1;
        do {
            i  = 1;
            console.log(i);
            let condJaq;
            if (data[i].poster_path == null) {
                condJaq = urlNoCover;
            } else {
                condJaq = urlJaq   data[i].poster_path;
            };
            template  = '<a href="#" id="prez_jaquetteDiv" ><p >'   data[i].title   '</p><img src="'   condJaq   '"  /></a>';
            $("#prez_choiseJaq").html(template);
        } while (i < data.length - 1);
    };
};

CodePudding user response:

There are so many issues here it's difficult to explain why your code isn't working. The issue with the for loop is a candidate for the error you didn't share, but there others.

The primary problem is that you were not adding a click handler for your links.

I've converted your code from module based JS (because I believe that's difficult to do in a snippet), mocked the Movie API call and cleaned up the code to remove most unnecessary globals, leverage jQuery more, and fix the for loop.

var array = {
    key: "exemple",
    urlMovie: 'https://api.themoviedb.org/3/search/movie?api_key=',
    urlSerie: 'https://api.themoviedb.org/3/search/tv?api_key=',
    urlImg: 'styles/prez/img/',
    urlJaq: "https://image.tmdb.org/t/p/w154",
    noCover: "no_cover.jpeg",
};

function mock_fetch(url, rep) {
    const query = url   "&language=fr-FR&query="   rep   "&page=1&include_adult=false"
    // response = await fetch(query);
    // return await reponse.json()
    return { results: [{ poster_path: "This is the poster path"
                       , title: rep
                       }
                      ,{ poster_path: "Some other path"
                       , title: "Some other movie"
                       }
                      ]
           }
}

async function getValue(inputRep) {
    let data;
    try {
        const responseData = mock_fetch(array.urlMovie   array.key, inputRep);
        data = responseData?.results;
        if (!data.length) {
            alert("Le film que vous demandez n'est pas disponible !");
        } else {
            viewPoster(data);
        }
    } catch (error) {
        console.error(error);
    }
    return data;
};

function viewPoster(data) {
    $("#prez_choiseJaq").css("display", "inline-grid");
    var template = "";
    data.forEach( (film, index) => {
        template  = `<a href="#" id="prez_jaquetteDiv"  data-index=${index}><p >${film.title}</p><img src="${film.poster_path?(array.urlJaq   film.poster_path):array.urlImg array.noCover}"  /></a>`;
    })
    $("#prez_choiseJaq").html(template);
};

function selectMovie(event) {
    event.preventDefault();
    getValue($('#prez_input').val());
}

function doSomethingWithFilm(event) {
    console.log(`You clicked film number ${$(this).data('index')}`)
}

function init() {
    $('#prez_input').keypress(event => { event.key === "Enter" && selectMovie(event) });
    $('#prez_btn').on("click", selectMovie);
    // Add the click handler for the links as a delegate because the links do not exist at the time this code is executed
    $(document).on("click", ".prez_col", doSomethingWithFilm);
}

$(init)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</script>
</head>
<body>
<div id="prez_rech" >
    <label for="fname">Recherche du film :</label>
    <input type="text" placeholder="Entrez votre film ici" id="prez_input">
    <xf:button type="button" id="prez_btn">Rechercher</xf:button>
</div>

<div id="prez_choiseJaq"></div>
</body>
</html>

CodePudding user response:

I just ran the test again and did the following:

template  = '<a href="#" onclick="'   selected(i)   '" id="prez_jaquetteDiv" ><p >'   data[i].title   '</p><img src="'   condJaq   '"  /></a>';
$("#prez_choiseJaq").html(template);

function selected(arg) {
    console.log(arg);
};

and in fact I have no error, nothing happens!

  • Related