Planning Week 5 - kiara1404/so-nuts Wiki

De laatste week van de meesterproef alweer... Ik moet nog veel te veel doen, geen idee of alles gaat lukken. Ik ben deze week als een gek JavaScript gaan schrijven.

Clientside JS

Om de progressbars te laten werken heb ik veel verschillende manieren geprobeerd. Veel werkte niet. Toen kam ik een filmpje tegen waarin ze het vrij simpel deden. Dit werkte eindelijk bij mij, alleen is het niet de meest optimale manier. Er wordt namelijk gebruik gemaakt van inline styling en ik weet dat dit een bad practice is. Nu heb ik er toch voor gekozen om dit te gebruiken omdat mijn verlangen om een dynamische progressBar te hebben erg groot was. Ik heb nog naar alternatieve manieren gezocht maar al deze manieren waren iets te hoog gegrepen voor mij en aangezien ik dit uitgesteld heb naar de allerlaatste week, probeerde ik te doen wat ik kon. Ik heb ook nog geprobeerd om een dynamische functie te schrijven zodat ik deze overal voor kon gebruiken maar dit is niet gelukt. Ik heb nu een functie per progressbar.

Code voor progressBar op het dashboard
if(dashboardPage){
    const kcalValue = document.querySelector('.kcal_value').innerHTML;
    const eiwitValue = document.querySelector('.eiwit_value').innerHTML;
    const groenteValue = document.querySelector('.groente_value').innerHTML;
    const kcalGoal = document.querySelector('.kcal_goal').innerHTML;
    const eiwitGoal = document.querySelector('.eiwit_goal').innerHTML;
    const groenteGoal = document.querySelector('.groente_goal').innerHTML;
    const currKcalGoal = kcalValue / kcalGoal;
    const currEiwitGoal = eiwitValue / eiwitGoal;
    const currGroenteGoal = groenteValue / groenteGoal;
    const voedselAverage = (currKcalGoal + currEiwitGoal + currGroenteGoal) / 3 * 100;


function bewegingProgressBar() {
    let progress = document.querySelector('.dashboard .container:nth-of-type(1) .progressBar')
    const value = document.querySelector('#beweging_value').innerHTML;
    const goal = document.querySelector('#beweging_goal').innerHTML;
    const currGoal = value / goal;
    const width = currGoal * 100 + '%';
    progress.style.width = width;
    }

 function voedingProgressBar() {
        progress = document.querySelector('.dashboard .container:nth-of-type(2) .progressBar');
        progress.style.width = voedselAverage + '%';
    }
}

Niet aleen heb ik ervoor gezorgd dat wanneer het doel op het dashboard gehaald is, de progressbar helemaal vol is. Ik heb het ook werkend gekregen dat de checkmark groen kleurt.

Checkmark validation code

HTML & EJS

            <div class="pbContainer">
                <div class="progressBar"></div>
            </div>
            <div>
                <% let totalMin = cardioData + krachtData %>
                <% if(cardioData && krachtData) { %>
                <p>
                    <span id="beweging_value">
                        <%= totalMin %>
                    </span>/week
                </p>
                <% } %>
                <ul>
                    <li>vandaag: 0</li>
                    <li>doel: <span id="beweging_goal"> 150</span></li>
                </ul>
            </div>
            <%- include('../partials/checkmark.ejs') %>

JS

goalAchieved(1, 'container', document.querySelector('#beweging_value').innerHTML);
goalAchieved(2, 'container', (voedselAverage));

function goalAchieved(x, el, value) {
    const checkmark = document.querySelector(`.${el}:nth-of-type(${x}) .checkmark i`);
    console.log(value)
    if (value >= 100) {
        addClass(checkmark, 'goal_achieved');
    }
}

Klooien met node FileSystem.

Er kan maar één object aan een json file worden toegevoegd en elke keer als je nieuwe gegevens toevoegd, worden de oude overschreven. Ik had eerst één form waarin je cardio en kracht tegelijk kon toevoegen. Alleen dit zorgde ervor dat cardio en kracht samen in één object zaten en er maar één waarde elke keer toegevoegd werd tenzij je twee activiteiten tegelijk zou invoeren. Ik vond dit niet bevordelijk voor de user experience en heb toen ook nog gekeken of ik met localStorage kon werken maar dit zou mij teveel tijd kosten om uit te vogelen aangezien ik daar nog nooit mee had gewerkt. Ook is het niet handig want ik wilde dat mijn formulieren nog verstuurd konden worden zonder clientside JS. Uiteindelijk heb ik dus besloten om het apart te doen. Een apart json file voor cardio en aparte file voor beweging(etc. voor voeding) Hoe ziet die code er dan uit? Ik had meerdere files namelijk nog nooit gedaan.

Post request per categorie
// index.js
app.post('/added_cardio', (req, res) => {
    let cardioStringData;
    const cardioData = {
        "trainingType": req.body.cardio_type,
        "minTraining": req.body.cardio_duration
    }
    cardioStringData = JSON.stringify(cardioData);


    fs.writeFile('public/json/cardio.json', cardioStringData, (err, data) => {
        if (data) {
            cardioStringData = JSON.parse(data)
        }
        if (err) {
            console.log(err)
        }
    });

    res.redirect('training')

})

Hoe stuur je dan meerdere json files mee in de .get? Ik wist dit ook niet. Na lang zoeken op het internet kwam ik op deze functie uit en na wat aanpassingen werkte het ook! Je moet hiervoor wel een het npm package async installeren. Ik kwam daarna ook nog op het probleem dat de data die ik wilde laten zien, als string ingeladen werd. Dit was een probleem omdat ik graag waardes bij elkaar wilde gaan optellen. Dus daarom de .parseInt() functie.

.get functie van dashboard
//dashboard
app.get('/dashboard', (req, res) => {
    const files = ['public/json/cardio.json', 'public/json/kracht.json', 'public/json/kcal.json', 'public/json/eiwitten.json', 'public/json/groente.json'];
    // got this function from stackOverflow: https://stackoverflow.com/questions/58424336/reading-multiple-files-asynchronously-in-node-js
    async.map(files, fs.readFile, function (err, data) {
        let stringDataCardio = JSON.parse(data[0])
        let stringDataKracht = JSON.parse(data[1])
        let stringDataKcal = JSON.parse(data[2]);
        let stringDataEiwitten = JSON.parse(data[3]);
        let stringDataGroente = JSON.parse(data[4]);

        let kcalData = parseInt(stringDataKcal.kcal);
        let eiwitData = parseInt(stringDataEiwitten.eiwitten);
        let groenteData = parseInt(stringDataGroente.groente);
        let krachtData = parseInt(stringDataKracht.minTraining)
        let cardioData = parseInt(stringDataCardio.minTraining)
        console.log(cardioData)
        console.log(krachtData)

        res.render('pages/dashboard', {
            cardioData: cardioData,
            krachtData: krachtData,
            cardioType: stringDataCardio,
            kcalData: kcalData,
            eiwitData: eiwitData,
            groenteData: groenteData
        });
    })
});

Progressie pagina gemaakt

Ik heb lang nagedacht over de content van deze pagina. Ik wilde graag de doelen laten zien maar ook wat tips meegeven. Het idee is dat de tips getoond worden op basis van welke doelen minder goed gaan. Dit om de gebruiker te motiveren om op die doelen te letten.

Wishlist

Omdat ik best wel lang heb gewacht met het schrijven van een paar core functionaliteiten, ben ik erachter gekomen dat ik mezelf een beetje in de vingers heb gesneden. Want doordat ik deze week daarmee aan de slag ben gegaan, kwam ik weer tot nieuwe inzichten die ik graag had willen implemeteren maar die helaas niet meer kunnen door gebrek aan tijd.

  • Ik wilde bij resultaten pagina, de geselecteerde doelen graag in een json file zetten en mee sturen naar het dashboard zodat het dynamischer was geweest.
  • Ik had graag een optie gewild waarin de gebruiker zijn eigen doelen had kunnen aanpassen.
  • Ik had erg graag gewild dat alle ingevoerde data opgeslagen in een json zou worden zodat je echt data per week had kunnen bekijken.
  • Ik had graag wat meer willen doen met de nieuwe API van Chippr maar dit was te moeilijk om in een week te implementeren.
  • Input van het formulier willen opslaan in localStorage.
⚠️ **GitHub.com Fallback** ⚠️