Generowanie html po klikneciu w button, dane z fetch api

0

Witam, uczę się js i chciałbym pobrać liste użytkowników za pomocą fetch api, następnie dodawać do html po kolei każdego użytkownika po kliknięciu w button. Nie rozumiem dlaczego createUser() wykonuje się tylko raz. Mogę dodać tylko 1 użytkownika po kliknięciu w button. Proszę o jakieś wskazówki.

function createUser(){
        
        let usersTab = [];
        let tabTemplateUser = [];
        let tmp = 0;
        const userWrap = document.getElementById('userWrap');
        const addUserBtn = document.getElementById('addUser');

        function setUserTab(tab){
            usersTab = tab;
        }
        
        function makeTemplate(){
            usersTab.forEach(user =>{
                let template = `
                <div class="userBox" style="margin-top:20px;">
                    <h2>Nazwa: ${user.name}</h2> 
                    <h2>Nazwa użytkownika: ${user.username}</h2>
                    <h2>Email: ${user.email}</h2>
                </div>`

                tabTemplateUser.push(template);

            })
        }
        
        function addUser(){
            userWrap.innerHTML += tabTemplateUser[tmp]
            tmp++
        }

        
        fetch("https://jsonplaceholder.typicode.com/users")
            .then(resp => resp.json())
            .then(json => setUserTab(json))
            .then( () =>  makeTemplate())
            .then( () =>  addUser())   
        
            .catch(function (error) {
                console.log('Request failed', error);
            });

    }

    const addUserBtn = document.getElementById('addUser');
    addUserBtn.addEventListener('click', createUser)

0

Prawdopodobnie Twój skrypt się wykrzacza i przestaje w ogóle działać; co pokazuje Ci konsola JS w narzędziach deweloperskich po naciśnięciu przycisku?

0

Wyświetla dane 1 użytkownika i nie pokazuje żadnych błędów. Po kolejnym kliknięciu nic się nie dzieje i również żadnych błędów / komunikatów.

0

Oki, no to pora na najprostszą istniejącą metodę debugowania: na samym początku funkcji createUser() umieść console.log('test'); i zobacz czy po drugim naciśnięciu przycisku coś pojawia się w konsoli JSa.

Disclaimer: jeśli chcesz nauczyć się czegoś lepszego, poczytaj o instrukcji debugger;.

0

Funkcja odpala się tylko raz i wyświetla się raz "test", po kolejnych kliknięciach żadnych komunikatów. Dlatego też mam problem z rozwiązaniem..

1

Zrobilem Ci przyklad online: https://jsfiddle.net/jsmbax3v/ czy dziala on tak jak sobie zalozyles?

1

Dlatego też mam problem z rozwiązaniem

Powoli, powoli, dopiero zaczynamy :-)

Usuń całe to wywołanie fetch("https://jsonplaceholder.typicode.com/users") (całe wyrażenie) i zobacz ponownie.

0

Tak teraz się wykonuje, czyli problem jest fetchu ? Czy w któreś w funkcji która jest wywoływana. Nie rozumiem dlaczego nie ma komunikatu o błędzie.

0

Powoli :-)

Teraz zrób:

        fetch("https://jsonplaceholder.typicode.com/users")
            .then(resp => resp.json())
            .catch(function (error) {
                console.log('Request failed', error);
            });

Btw, zadałem Ci jeszcze pytanie w komentarzu:

w markupie (w HTMLu) Twój addUser nie znajduje się przypadkiem wewnątrz userWrap, prawda?`

0

Tak, znajduje się wewnątrz. Po wyjęciu go na zewnątrz i wyciągnięciu zmiennej counter poza funkcje (globalnie), dziala tak jak należy. Pytanie czy to dobra praktyka i czy ten kod jest w miare okej ? Nie rozumiem czemu button wewnątrz diva takie dziwne działanie powodował.

let couter = 0;
    
    function createUser(){
        
        console.log('test')
        
        let usersTab = [];
        let tabTemplateUser = [];
        
        const userWrap = document.getElementById('userWrap');
        const addUserBtn = document.getElementById('addUser');

        function setUserTab(tab){
            usersTab = tab;
        }
        
        function makeTemplate(){
            usersTab.forEach(user =>{
                let template = `
                <div class="userBox" style="margin-top:20px;">
                    <h2>Nazwa: ${user.name}</h2> 
                    <h2>Nazwa użytkownika: ${user.username}</h2>
                    <h2>Email: ${user.email}</h2>
                </div>`

                tabTemplateUser.push(template);

            })
        }
        
        function addUser(){
            userWrap.innerHTML += tabTemplateUser[couter]
            couter++
            console.log(couter)
        }

        
        fetch("https://jsonplaceholder.typicode.com/users")
            .then(resp => resp.json())
            .then(json => setUserTab(json))
            .then( (json) =>  makeTemplate())
            .then( (json) =>  addUser())   
        
            .catch(function (error) {
                console.log('Request failed', error);
            });

    }

    const addUserBtn = document.getElementById('addUser');
    addUserBtn.addEventListener('click', createUser)
1

Zatem cały problem rozwiązany - robiąc:

userWrap.innerHTML += tabTemplateUser[tmp]

... powodujesz przebudowanie całego DOMu wewnątrz danego elementu, co z kolei niszczy wszystkie przypisane wewnątrz event listenery.

Powinieneś albo rozdzielić obydwa kontenery od siebie (tak, aby button nie znajdował się wewnątrz wrappera), albo nie wykorzystywać innerHTML += ..., tylko robić append (bądź podobne bajery).

0

Rozumiem, dziękuje za pomoc ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1