node.js mitä eroa näillä kahdella on tässä tapauksessa ( .push() ja = )

Liittynyt
17.10.2016
Viestejä
486
Olen harjoittelemassa node.js perusteita koska alkaa olla niin yleinen kieli ylläpitää servereitä. Testasin arrayss olefaa filter funktiota ja sen kanssa tuli ongelmia riippuen siitä miten JSON oli lisätty taulukkoon.

Minulla on taulukko joka on tälläinen:

Koodi:
var addNote = (title, body) => {
    var notes = [];
    var note = {
        title: title, // Take parameter from parameter list
        body: body // Take parameter from parameter list
    };

    try {
        var notesString = fs.readFileSync('notes-data.json');
        var test = JSON.parse(notesString);
        // Add previously loaded files
        notes = test;
       // notes.push(test);
    } catch(e) {

    }

Riippuen siitä lisäänkö JSONin taulukkoon komennolla notes = test;
tai notes.push(test) filtteri joko toimii tai ei toimi ollenkaan.

Filtterikomento minulla on näin:
Koodi:
    // Filter is callback function. Fills array if requirement is met.
    var duplicateNotes = notes.filter((note) => {
        console.log(note.title)
        return notew.title == title;
    });

pushia käyttäessä note.title muuttuu muotoon undefined. Mistä tämä johtuu? Mitä tuo notes = test; ylipäätänsä tekee eri tavalla kuin .push(test) ?

Osaisiko joku kertoa :).
 
Lyhkäsesti;
Array notes on aluksi tyhjä array, [].
Jos käytät sijoitusoperaattoria, sijoitat tyhjän arrayn tilalle arrayn test, jolloin notes on esim. ['foo','bar'].
Pushilla taas et sijoita muuttujaan uutta arvoa, vaan lykkäät sen tuohon notes arrayhyn, jolloin lopputulos olisi [['foo','bar']].
Ja tästä syystä filtterisi ei toimi pushilla, koska se saa silmukkamuuttujana koko tuon test-arrayn, ei sen ensimmäistä jäsentä.

E: Ja note.title on luonnollisesti undefined, koska note on jäljemmässä tapauksessa itseasiassa koko tuo test-array, jolla ei ole propertyä (mikä lie suomenkielinen termi) title.

Lähetetty minun ONEPLUS A3003 laitteesta Tapatalkilla
 
Kuten yllä jo sivuttiin, taulukon alkiossa oleva objekti on eri asia, kuin muuttuja, jonka arvona on objekti (vaikka taulukkot ovat myös objekteja). Java scripitissä tietotyypit ovat dynaamisiä ja voit tilanteesta riippuen asettaa samaan muuttujaan eri tietotyyppejä.
 
Hyödynnetään tätä vielä. Minkä takia tämä ei toimi?

Koodi:
let geocodeData = "";

geocode.geocodeAddress(argv.address, (errorMessage, results) => {
  
    if (errorMessage) {
        console.log(errorMessage)
    } else {
       geocodeData = JSON.stringify(results, undefined, 2);
       console.log(geocodeData);
    }
});

// Tyhjää tulee
console.log(geocodeData);

Yritän siis, että geocodeData muuttujaan tulisi nuo geotiedot jotka palautuvat funktiosta. Mikäli tulostan geokoodit ylempänä olevan funktion sisällä, se toimii. Mikäli sitten yritän tulostaa samoja koodeja funktion ulkopuolella, koko geocodeData on tyhjä. Ilmeisesti muuttuja ei ole globaali ja funktion sisällä sitä editoidaan vain paikallisesti, mutta mikä on ratkaisu tähän? Miten saan tuolla funktiossa olevat datat tuohon geomuuttujaan, jotta voin hyödyntää sitä muualla koodissa?
 
geocodeAddress tekee asynkronisen HTTP-kutsun googlen palvelimelle, mikä tarkoittaa sitä että suoritus koodissa jatkuu, ja tuo tarjoamasi callback suoritetaan sitten joskus kun vastaus tulee.

Ja tästä johtuen jälkimmäinen console.log suoritetaan ennenkuin vastaus on tullut -> muuttujaan ei ole vielä ehditty sijoittaa mitään arvoa.

Lähetetty minun ONEPLUS A3003 laitteesta Tapatalkilla
 
Suosittelen muuten että lukaiset esim. tästä JS:n promiseista;
Promise

Peruskäytön oppii nopeasti, ja helpottaa kummasti luettavan koodin kirjoittamista aina kun jotain täytyy (/haluaa) hakea asynkronisesti.

Lähetetty minun ONEPLUS A3003 laitteesta Tapatalkilla
 
Ja (taas) ylläolevaan pienenä lisäyksenä; kun kerran kirjoitat node-koodia niin opiskele promisen perusteet kuten yllä jo mainittiin ja sitten voit käyttää vielä luettavampaa sokerikuorrutettua async + await syntaksia kun ymmärrät miten promiset toimii konepellin alla.

ps. ja täytyy myöntää että itselleni oli ehdottomasti vaikeinta JS:ssä callback:n käyttö muiden ohjelmointikielien jälkeen, vaikka se on funktionaalisen ohjelmoinnin perusteita.
 
Viimeksi muokattu:
Seuraava asia listassa on tuo promisen käyttö. callbackeja myös koittanut tässä harjoitella. Selkeni ainakin itselleni huomattavasti miten tuo callback käytännössä toimii kun en käyttänyt nuolifunktioita koodin seassa, vaan ulkoistin kaikki. Näissä funktioissa sitten kutsuin sitä callbackia parametreineen.
 
Myös: jos kerta hyödynnät ES6 ominaisuuksia kuten fat arrowia, niin älä enää turhaan käytä varria vaan aina const (ellei ole syytä muuttaa arvoa, jolloin let).

Spread-operaattori on ehkä uuden javascriptin hyödyllisin asia, jolloin ei ole tapana enää edes sijoittaa asioita taulukoihin tai objekteihin, vaan tehdä niistä kopioita tarpeen tullen. Opin itsekin tähän uudempaan syntaksiin vasta ~viimeisen puolen vuoden sisällä, mutta koodista on tullut ihan uskomattoman paljon lyhyempää pysyen samalla varsin luettavana ja vähemmän virhealttiina. Eslint on aika pop.

Itse pitäisi päästä vielä typescriptiin kunnolla sisään, en jotenkin saa kiinni kaikista sen hyödyistä, vaikka tuttu sitä kehuukin maasta taivaisiin...
 
ES6 on preprocessoitu ES5:ksi. kuten typescrict/jsx -> ES6:ksi. varrin ja lettin ero on hoastingissä. var hoastataan aina let taas ei. let toisaalta maksaa hivenen performancessa. Promiseista sen verran että sitä hoilotetaan asynkronous sitä asynkronous tätä. Se taas ei tarkoita säikeistystä. ASI on ehkäpä huonoin idea koko JavaScriptissä.
 
ES6 on preprocessoitu ES5:ksi. kuten typescrict/jsx -> ES6:ksi.

Mihin tuo nyt liittyi? Ja ei ne automaattisesti käänny mihinkään. ES6:ta voi ajaa natiivistikin uusissa selaimissa vaihtelevalla tuella. Ja vaikka transpiloisi ES5:ksi, ei se silti poista millään tavalla constin ja letin hyviä puolia.

varrin ja lettin ero on hoastingissä. var hoastataan aina let taas ei. let toisaalta maksaa hivenen performancessa.

Se on muuten "hoisting". Ja isompi ero on omasta mielestäni muuttujan näkyvyysalue. Var:ia käyettäessä scope on funktio tai funktion ulkopuolella muuttujasta tulee globaali. Let:iä käyettäessä näkyvyysalue on lohko - usein hyvinkin toivottava piirre.

Suorituskyky harvemmin on ongelma noiden välillä valittaessa, ja erokin riippuu ihan enginestä/kääntäjästä ja tilanteesta. Kommenttisi suorituskyvystä on ilman yksityiskohtia täysin yhdentekevä.

Promiseista sen verran että sitä hoilotetaan asynkronous sitä asynkronous tätä. Se taas ei tarkoita säikeistystä.

Kuka hoilottaa? Väittikö joku, että tarkoittaa? Promiset tekevät koodista luettavampaa ja ylläpidettävämpää. Ja callbackit/promiset mahdollistavat järkevän toiminnan pitkien latenssien nettisoftissa: callback ei blokkaa muuta koodia, vaan se suoritetaan vasta kun esim. data on saatu API:sta.

ASI on ehkäpä huonoin idea koko JavaScriptissä.

Tämänkin takia linterin käyttö on erittäin suositeltavaa.
 
Mihin tuo nyt liittyi? Ja ei ne automaattisesti käänny mihinkään. ES6:ta voi ajaa natiivistikin uusissa selaimissa vaihtelevalla tuella. Ja vaikka transpiloisi ES5:ksi, ei se silti poista millään tavalla constin ja letin hyviä puolia.



Se on muuten "hoisting". Ja isompi ero on omasta mielestäni muuttujan näkyvyysalue. Var:ia käyettäessä scope on funktio tai funktion ulkopuolella muuttujasta tulee globaali. Let:iä käyettäessä näkyvyysalue on lohko - usein hyvinkin toivottava piirre.

Suorituskyky harvemmin on ongelma noiden välillä valittaessa, ja erokin riippuu ihan enginestä/kääntäjästä ja tilanteesta. Kommenttisi suorituskyvystä on ilman yksityiskohtia täysin yhdentekevä.



Kuka hoilottaa? Väittikö joku, että tarkoittaa? Promiset tekevät koodista luettavampaa ja ylläpidettävämpää. Ja callbackit/promiset mahdollistavat järkevän toiminnan pitkien latenssien nettisoftissa: callback ei blokkaa muuta koodia, vaan se suoritetaan vasta kun esim. data on saatu API:sta.



Tämänkin takia linterin käyttö on erittäin suositeltavaa.

Benchmarkkasin. Ja huomasin että JavaScript ei ole turing complete - kieli niinkuin flang on. Taulukon hakuajat eivät ole O(1) niinkuin oikeissa kielissä. Oikean taulukon puute on vakava ongelma. Pitäisi pystyä varaamaan heappiin yhtenäinen muistiavaruus constant hakuajoilla. Tietysti oikea ohjelmointi on eri asia kuin html:n tulostus. Joten en oleta että ymmärtäisit muistin käsittelystä yhtään mitään.

Lol. It's not a bug it's a feature!
Pitäisikö minunkin kirjoittaa flangiin linteri korjaamaan bugit vai korjata kieli suoraan?

standard-linter nimenomaan kieltää puolipisteen käytön. Enpä ole tyhmempää kuullut.
JavaScript Standard Style
 
Java Script nyt on täynnä ongelmia verrattuina muihin kieliin, mutta niin se vain on maailman suosituin ohjelmointikieli. Vaikka se ei ole Flang.
 
Ei noihin mystikon viesteihin voi todeta muuta kuin :facepalm: Huh, mitä settiä taas :rofl:
 
Kyselläänpä vielä. Minulla on tullut ongelmia tehdä handlebarin IF-lauseita. Ilmeisesti pitäisi rekisteröidä helpperi-luokka ja käyttää sitä hyväksi, mutta ei oikein leikkaa, millä tavalla se kannattaisi tehdä.

Minulla on koodi, joka hakee tietokannasta tavaraa drop-down valikossa olevan tiedon perusteella. Haluaisin niin, että kun haku on tehty niin viimeisin haku jäisi siihen drop-downiin näkyviin, eikä se palautuisi aina oletukseen.

Minulla on GetAll functiossa sekä get että post metodit. get Vetää oletuksena kaikki listalla olevat tiedot ja kun erikseen valitsee jonkun niin ajetaan post.

Koodi:
        // Get method of GetAll
        app.get('/GetAll', (request, response) => {
            DBConnect.GetAllFromDatabase(request.body.Profession, "get", connection, (error, results, fields) => {
               
                response.render('SearchResults.hbs', {
                    databaseResults: results
                });
            });
        });


        // Post method of GetAll
        app.post('/GetAll', urlencodedParser, (request, response) => {
            DBConnect.GetAllFromDatabase(request.body.Profession, "post", connection, (error, results, fields) => {
           
                response.render('SearchResults.hbs', {
                    databaseResults: results,
                    ProfessionData: request.body.Profession,
                });
            });
        });


        app.get('/InsertToDatabase/:name/:profession/:subject/:defect/:location', (request, response) => {
            DBConnect.InsertToDatabase(request.params.name, request.params.profession, request.params.subject, request.params.defect, request.params.location, "New", Date.now(), connection, (error, results, fields) => {
                if (error) {
                    let Message = {
                        Message: "Error Occurred, please try again later"
                    }
                    response.send(JSON.stringify(Message));
                }
                else {
                    let Message = {
                        Message: "Added to database successfully"
                    }
                    response.send(JSON.stringify(Message));                   
                }               
            });
        });

Sivulla, joka renderöidään on koodia:
Koodi:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Here are the list of current Defects:</title>
</head>

<body>
    <h1>Welcome</h1>

    Show defects from:
    <form action="/GetAll" method='post'>
        <select name="Profession">
            <option value="Architect">Architect</option>
            <option value="IT-asiantuntija">IT-department</option>
            <option value="Siivooja">Cleaning department</option>
            <option value="Visitor">Visitor</option>
        </select>
        <br><br>
        <input type="submit">
    </form>

    <hr />

    {{# each databaseResults }}
    <p>Reporter: {{ this.Name }}</p>
    <p>Profession: {{ this.Profession }}</p>
    <p>Subject: {{ this.Subject }}</p>
    <p>Defect: {{ this.Defect }}</p>
    <p>Location: {{ this.Location }}</p>
    <p>Current State: {{ this.State }}</p>
    <p>Defect reported: {{ this.Timestamp }}</p>
    <br />

    <hr />
    {{/each}}


</body>

</html>

Nyt käytännössä aina päällimmäisenä on tuo Architect. Haluaisin, että mikäli esim. kaikki IT-asiantuntijat haetaan tietokannasta niin HTML koodiin tulisi läsänä vaikkapa näin:
Koodi:
<option selected=selected value="IT-asiantuntija">IT-department</option>

Onkos tuohon minkälainen keino paras? Lisäsin Post metodin mukaan tuon ProfessionData: request.body.Profession, jota ajattelin hyödyntää. Sen mukana tulee viimeisin valittu tieto.
 
Nyt menee kyllä GETien ja POSTien käyttötarkoitus aika pahasti sekaisin. Esimerkiksi tuo tietoja tietokantaan tallentava GET-kutsun urli on vähintäänkin... mielenkiintoinen.

Toinen on tietysti Handlebars, joka noh, on ihan kiva staattisen datan näyttämiseen, vaikkakin aika rajoittunut ja helposti tosi epäselvä.

Tässä kohtaa auttaisi taas hyvä opetusmateriaali satunnaisten foorumiauttajien sijaan. Jos haluat pysyä Moustache/Handlebars -linjalla, voisi hyvä materiaali olla Web-selainohjelmointi , jos taas haluat siirtyä vähän modernimpaan juttuun (jossa Express/Node käsitellään osassa 4), niin tarjolla olisi esimerkiksi Full stack -websovelluskehitys

Molemmat materiaalit ovat Helsingin Yliopiston, mutta vapaasti käytettävissä.
 
Nyt menee kyllä GETien ja POSTien käyttötarkoitus aika pahasti sekaisin. Esimerkiksi tuo tietoja tietokantaan tallentava GET-kutsun urli on vähintäänkin... mielenkiintoinen.

Toinen on tietysti Handlebars, joka noh, on ihan kiva staattisen datan näyttämiseen, vaikkakin aika rajoittunut ja helposti tosi epäselvä.

Tässä kohtaa auttaisi taas hyvä opetusmateriaali satunnaisten foorumiauttajien sijaan. Jos haluat pysyä Moustache/Handlebars -linjalla, voisi hyvä materiaali olla Web-selainohjelmointi , jos taas haluat siirtyä vähän modernimpaan juttuun (jossa Express/Node käsitellään osassa 4), niin tarjolla olisi esimerkiksi Full stack -websovelluskehitys

Molemmat materiaalit ovat Helsingin Yliopiston, mutta vapaasti käytettävissä.
Käyn samalla Udemyn tutoriaalisarjaa läpi. Koitan aina välillä tehdä jotain omia juttuja ja testailla. Youtubesta katsoin tuota get/post ohjeita myös ja siellä oli tehty tuo sivulle siirtyminen juurikin kahdella tavalla (post ja get). Jos tuon sivun avaa normaalisti niin oletuksenahan on tuo get ja jos formin valintaa painaa ja se menee postia niin sittenhän tulee vaihtoehtoisesti tuo post muoto. Joten jos tuota app.get ja app.post ei käytä molempia niin miten se sitten pitäisi tehdä?

Nuo InsertToDatabasessa olevat on tarkoitus olla parameterja. Eli kun selaimella menee sivulla ja laittaa loppuun esim. InsertToDatabase/Mikko/IT-henkilö/Vikaa laitteessa/Laite ei lähde päälle/Kerros 2, huone 5/ Niin tuolla DBConnect.js sivulla otetaan nuo parametrit ja laitetaan tietokantaan. Onko tuo väärä tapa?
 
Käyn samalla Udemyn tutoriaalisarjaa läpi. Koitan aina välillä tehdä jotain omia juttuja ja testailla. Youtubesta katsoin tuota get/post ohjeita myös ja siellä oli tehty tuo sivulle siirtyminen juurikin kahdella tavalla (post ja get). Jos tuon sivun avaa normaalisti niin oletuksenahan on tuo get ja jos formin valintaa painaa ja se menee postia niin sittenhän tulee vaihtoehtoisesti tuo post muoto. Joten jos tuota app.get ja app.post ei käytä molempia niin miten se sitten pitäisi tehdä?

Nuo InsertToDatabasessa olevat on tarkoitus olla parameterja. Eli kun selaimella menee sivulla ja laittaa loppuun esim. InsertToDatabase/Mikko/IT-henkilö/Vikaa laitteessa/Laite ei lähde päälle/Kerros 2, huone 5/ Niin tuolla DBConnect.js sivulla otetaan nuo parametrit ja laitetaan tietokantaan. Onko tuo väärä tapa?
Ongelma tässä on varmaan se, että melko yleisesti taidetaan olettaa, ettei GET-pyyntö muuta palvelimella mitään - esimerkiksi lisäämällä tietokantaan dataa. Jos haluat lisätä tietokantaan dataa, lienee parempi käyttää POST-pyyntöä.
 

Statistiikka

Viestiketjuista
261 844
Viestejä
4 548 950
Jäsenet
74 855
Uusin jäsen
Nåksuu

Hinta.fi

Back
Ylös Bottom