Flaskista Flask+Reactiin

Liittynyt
07.01.2021
Viestejä
678
Hetznerin ohjeet oli jotenkin sekavammat, pitääpä kokeilla noita.

Mistä muuten Paapaa, näit tuon virheilmoituksen? Minä en huomannut kuin tuon postaamani konsolista.
 
Liittynyt
06.11.2016
Viestejä
1 750
Tuo codesandboxin konsolihan ei näytä oikein mitään extraa.
 
Liittynyt
17.10.2016
Viestejä
14 550
Toi HTTPS:n konffaaminen on oma suonsa, joka on ihan kiva tehdä manuaalisesti kerran pari kunhan hakee tuoreet ohjeet joissa kerrotaan mitä kaikkea kannattaa ottaa huomioon ja asettaa nginx:stä, mutta sitten se kannattaa koettaa automatisoida.

Jos käytät jotain palveluita, jotka osaavat hostata fronttia (Heroku, Netlify jne.), ne tekevät kaiken automaattisesti puolestasi. AWS:n S3-hostauksessa sama juttu, AWS hoitaa homman. Yleensä vielä ilman lisämaksua.

Jos taas on oma serveri, voi hyödyntää esim. jotain homman hoitavaa docker-palvelua, esim:


Kaikki muuttuu helpommin ylläpidettäväksi kun hyppäät Docker-maailmaan ja jätät kaiken itse konffaamisen taka-alalle.
 
Liittynyt
07.01.2021
Viestejä
678
Varmaan joo, mutta kun tämä on harrastus, johon on rajallinen määrä aikaa käytössä + minua ei oikeastaan kiinnosta nuo DevOps-hommat. Haluaako joku konffata Dockerit kuntoon? Olen sen verran koskenut, että ainakin konffeja tuntui riittävän.
 
Liittynyt
17.10.2016
Viestejä
14 550
Varmaan joo, mutta kun tämä on harrastus, johon on rajallinen määrä aikaa käytössä + minua ei oikeastaan kiinnosta nuo DevOps-hommat
Tervetuloa webbikehityksen maailmaan :D Opittavaa on loputtoman paljon, että kaikki palaset loksahtaa paikoilleen. Mutta kyllä mä rohkaisen opettelemaan tuotakin puolta. Lisää isosti ymmärrystä kaiken toiminnasta. Eikä noiden konffaaminen ole mitään ylitsepääsemättömän vaikeaa. Mutta Dockerin opettelua vaatii. Tässä pari loistavaa kurssia, ensimmäinen vain Dockeriin, toinen webbidevaukseen yleisesti:

Docker-kurssi: DevOps with Docker
Full Stack Open -kurssi: Full stack open 2021

Mutta jos et halua tehdä ihan kaikkea itse, niin sitten unohda oma palvelin, ja käytä jotain Herokua sen sijaan. Mutta siitä joutuu maksamaan pienen hinnan (ilmaisessa taitaa olla pieni viive kun appista ei käytetä ja se herätetään). En osaa hatusta heittää, mitä täysin ilmaisia vaihtoehtoja on olemassa Flask-bäkkärin ja React-frontin hostaamiseen.
 
Liittynyt
18.10.2016
Viestejä
272
Itsellä kombo Gandi/Namecheap --> Cloudflare --> Netlify / Heroku.

Kun on tuollainen react-äpsykkä niin varmaan Verceliin heittäisin sälät ja sitten jostain vaikkapa possu tai mongo siihen taustalle, jos aidosti on kannalle tarvetta. Toki middlewaren konffaamiset sekä Vercelillä että Netlifyllä on IMO taas oma opettelunsa vs. Node+Expressin tunkkaaminen Herokuun.

Itse siis ex-web, nykyään mobiilisovellus-devaaja. käyn silloin tällöin kurkkimassa, että miten webissä asiat tehdään ja menee kyllä hermot kerta kerrasta :D
 
Liittynyt
04.03.2017
Viestejä
282
Tai sitten vaan hoitaa sen https-sertifikaatin kuntoon sillä certbotilla ja jatkaa koodaamista.
 
  • Tykkää
Reactions: jad
Liittynyt
07.01.2021
Viestejä
678
Minä siis olen tuota ilmaista Herokua käyttänyt. Mutta heti kun pitää lisätä tietokanta, niin hinta pomppaa nykyiseen ratkaisuun verrattuna kolmin-nelinkertaiseksi. En minä melkein kahtakymppiä kuukaudessa viitsi tästä maksaa.

Kumma kun näitä servereitä pystyttiin ennen pyörittämään ilman Dockeria, mutta ei enää.
 
  • Tykkää
Reactions: jad
Liittynyt
17.10.2016
Viestejä
14 550
Kumma kun näitä servereitä pystyttiin ennen pyörittämään ilman Dockeria, mutta ei enää.
Öö, mikäs ihmeen kommentti tuo oikein on?? Tietenkin pystyy, mitä muuta kuvittelet? Docker vain helpottaa sitä asennusta ja ylläpitoa. Jos sua ei nappaa sen opettelu, niin siitä vaan asentamaan ja konffaamaan kaikki itse. Ja toivomaan, että osaat tehdä saman uudestaan kun se serveri menee nurin ja pitää aloittaa alusta, jos et sitä infran pystyttämistä ole automatisoinut. Lopulta huomaat kyllä, miksi ne kontit on keksitty. Voit sitten tulla lainaamaan tätä viestiäni.

Mutta tietenkin kaiken voi tehdä ns. pitkästä tavarasta. Vaikka kääntää sorsista jos sellaisesta nauttii. Ei siihen vaadita kuin aikaa ja kärsivällisyyttä.
 
Liittynyt
07.01.2021
Viestejä
678
No siis kun tuo sivusto pyörii jo jotenkin. Voitanko minä työajassa takaisin tuon serverin ylläpidossa jossain vaiheessa jos kulutan kymmeniä tunteja Dockerin opetteluun ja konffaamiseen? Ei ole suunnitelmissa tällä hetkellä tehdä muuta weppihommaa kuin tätä. Ja haluaisin tosiaan saada tästä Reactista joskus valmista, Dockerin opettelu ja konffaus lisää varmasti +3kk meikäläisen ajankäytöllä projektiin kestoa. Ja nykyisen etenemisen perusteella tässä React-hommassakin menee vielä kauan. Enkä koe hommaa alkuunkaan kiinnostavana, eli pakkopullaahan se olisi. Pakko vähän miettiä hyöty:panos-suhdetta, kun kukaan ei maksa palkkaa. Muutenhan se olisi sama mitä näppäilen, voin vaikka tunkata kesälomiin asti Dockeria eikä aikataulut ole minun ongelmani.

Tuosta serveristä ajetaan snapshot joka yö ja tallessa on viikon backupit. Toki jos nuokin feilaa, niin sitten on vähän huonompi homma.

Toisessa ketjussa ehdotettiin minulle Reactilla käyttöliittymän tekemistä. En silloin alkanut tekemään, ja hyvä niin, koska en tiedä olisiko koko sivusto vieläkään pystyssä. Nyt järjestelmään on mm. lisätty jo yli 1000 kansikuvaa ja rutkasti muuta tietoa sillä Flask-käyttöliittymällä. Tarkoitus on parantaa kokemusta ja lisätä tiettyjä parannuksia, joiden tekeminen nykyiseen on turhan työlästä. Lisäksi saan Reactilla tehtyä paremmin ylläpidettävää koodia. Eli tuollaisia Docker-hommia voin miettiä kunhan saan tämän React-homman kuosiin.
 

jad

Liittynyt
22.10.2016
Viestejä
1 210
Itsehän olen muutosvastarintainen vanha pieru, niin seuraavaan kannattaa suhtautua sen mukaan :)

Docker on nykypäivän PHP. PHP kärsii vieläkin siitä paskan kielen maineesta, joka aikanaan syntyi siitä, että PHP:llä oli aloittelijan helppo lähteä tekemään webbisovelluksia. Ja tämä johti siihen, että maailmalla on yhä tänä päivänä julmettu määrä paskaa tietoturvaongelmaista aloittelijoiden tekemää koodia tuotantoajossa.
Sama koskee nykypäivänä Dockeria, kun jotain ei osata, ratkaisuna on Dockerin käyttö ja se johtaa taas siihen, että opitaan käyttämään Dockeria, mutta se juuriongelma jää edelleen mustaksi laatikoksi mistä ei tiedä tai osaa mitään.

Tälläisessä pienessä harrasteprojektissa varsinkaan ei ole mitään järkeä alkaa ampumaan tykillä kärpästä ja virittämään jotain Docker ratkaisua näin triviaalin ongelman korjaamiseksi. Jos en väärin muista, niin taisit @Makis aiemmin kipuilla jonkun Nginx vhostinkin kanssa ? Jos löytyy luottoa random foorumikeskustelijaan, niin pistä privaviestiä, äkkiäkös nuo kuntoon säädetään.
 
Liittynyt
07.01.2021
Viestejä
678
Kyllä se nginx ihan kohtuudella sitten sujahti paikalleen. Pitää seuraavaksi SSL vaan säätää + kunhan saisin tuon käyttöliittymän Reactilla, niin sitten pitää miettiä miten nuo reititykset menisi. Mutta tähän React-hommaan menee vielä kuukausia.
 
Liittynyt
07.01.2021
Viestejä
678
Eipä kyllä tosiaan ollut noilla ohjeilla kummoinen homma laittaa certtejä kuntoon. Nyt sandboxikin "toimii", ihmeellinen bugi tuossa kontrollissa, jota ei ole omalla koneella. Lisää jostain sarakkeen nimen jokaiseen arvoon.
 
Liittynyt
07.01.2021
Viestejä
678
Taas riittää ihmettelemistä TypeScriptin kanssa.


nationalityFilterTemplate() aiheuttaa ajonaikaisen virheen, koska options:lla ei ole valueta eikä filterApplyCallbackia.

Tuo ColumnFilterElementType on kuitenkin editorin mukaan oikea tyyppi. Tuo on kuitenkin vähän kinkkisempi:
Koodi:
type ColumnFilterElementType = React.ReactNode | ((options: ColumnFilterElementTemplateOptions) => React.ReactNode);
Mietin ensin, että pitääkö tuossa tsekata, että parametri on tuota ColumnFilterElementTemplateOptions-interfacea, mutta sitä ei ole exportattu joten en ilmeisesti pysty tekemään sitä. Nuo kentät löytyvät nimittäin siitä. Valitettavasti tuon komponentin tekijän sivujen esimerkit on tällä hetkellä vain suoraan kopioitu JS-hooks-versiosta, eli tyyppimäärittelyt puuttuvat.
 
Liittynyt
17.10.2016
Viestejä
14 550
@Makis, vaikka sitä optionsin tyyppiä ei ole exportattu, niin saat sen kuntoon yksinkertaisesti määrittämällä sen nationalityFilterTemplate:n oikeaksi tyypiksi. TS antaa näin myös optionsille oikean tyypin automaattisesti. Eli:

Koodi:
const nationalityFilterTemplate: ColumnFilterElementType = (options) => ...
Mutta tuo toki korjaa vain käännöksenaikaisen tyypityksen. Ajonaikaisuus on sitten oma lukunsa.
 
Liittynyt
07.01.2021
Viestejä
678
En kyllä ymmärrä, miksi tuo toimii. Annetaan siis funktiolle tyyppi ja se jotenkin maagisesti johtaa siihen, että kääntäjä tietää parametrin tyypin? Yritin lueskella lisätietoja TS:n tyyppisysteemistä, mutta kun kaikki jutut tuntuvat olevan Aa-pe-lil-la on koi-ra -tasoa, niin ei ollut paljon hyötyä.

Mutta näköjään tuossa komponentissa on sellainen pikkujuttu, että se ei osaa sortata ääkkösiä oikein. Muutenkin pitää melkein tehdä lazy loading, mutta jotta sorttaus toimii sen kanssa, niin melkein pakko kanssa tehdä sorttaus ja filtteröinti backendissä. Mikä mutkistaakin mukavasti hommaa.
 
Liittynyt
17.10.2016
Viestejä
14 550
En kyllä ymmärrä, miksi tuo toimii. Annetaan siis funktiolle tyyppi ja se jotenkin maagisesti johtaa siihen, että kääntäjä tietää parametrin tyypin?
Tässä tapauksessa kääntäjä tietää, että jos määrittelet funktion juuri tuolla tyypillä, ei ole mitään muuta mahdollisuutta kuin että se parametrin tyyppi on ColumnFilterElementTemplateOptions. Se on ainoa tulkinta tyypin perusteella. TS osaa päätellä varsin paljon, eikä sille tarvitse eksplisiittisesti kertoa kaikkea. Joskus on useampi tulkinta, ja silloin pitää antaa lisää ohjausta, että kääntäjä käyttää oikeaa tyypitystä. Esim:

Koodi:
const strings = ['foo', 'bar']; // tyyppi string[]

const fooBars: Array<'foo' | 'bar'> = ['foo', 'bar']
; // tyyppi ('foo' | 'bar')[], eli mikä tahansa string ei käy
 
Liittynyt
07.01.2021
Viestejä
678
Äh, ei tuo certbot-himmeli sitten ihan putkeen mennytkään. Nyt ufw blokkaa yhteydet porttiin 3000, yritti sitten http:llä tai https:llä. Sama juttu portin 5000 kanssa. Yritin sallia nuo portit, mutta ei auta:
Koodi:
$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
Nginx Full                 ALLOW       Anywhere
OpenSSH                    ALLOW       Anywhere
3000                       ALLOW       Anywhere
5000                       ALLOW       Anywhere
Nginx Full (v6)            ALLOW       Anywhere (v6)
OpenSSH (v6)               ALLOW       Anywhere (v6)
3000 (v6)                  ALLOW       Anywhere (v6)
5000 (v6)                  ALLOW       Anywhere (v6)
3000/tcp:täkin kokeilin yhtä laihoin tuloksin. Ilmeisestikin systeemi hyväksyy nyt vain 80- ja 443-portit.
 

jad

Liittynyt
22.10.2016
Viestejä
1 210
Äh, ei tuo certbot-himmeli sitten ihan putkeen mennytkään. Nyt ufw blokkaa yhteydet porttiin 3000, yritti sitten http:llä tai https:llä. Sama juttu portin 5000 kanssa. Yritin sallia nuo portit, mutta ei auta:
Koodi:
$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
Nginx Full                 ALLOW       Anywhere
OpenSSH                    ALLOW       Anywhere
3000                       ALLOW       Anywhere
5000                       ALLOW       Anywhere
Nginx Full (v6)            ALLOW       Anywhere (v6)
OpenSSH (v6)               ALLOW       Anywhere (v6)
3000 (v6)                  ALLOW       Anywhere (v6)
5000 (v6)                  ALLOW       Anywhere (v6)
3000/tcp:täkin kokeilin yhtä laihoin tuloksin. Ilmeisestikin systeemi hyväksyy nyt vain 80- ja 443-portit.
Kyllä tuo äkkiseltään näyttäisi olevan ihan oikein. Voit tietysti varmistaa asian logeista 'sudo ufw logging on' jos ei jo ole päällä. Oletuksena ufw:n logit löytynevät /var/log/syslog:sta.
Edit: sudo ss -l -t -u komennolla vielä varmistat, että siellä joku on 3000/5000 porttia kuuntelemassa.
 

jad

Liittynyt
22.10.2016
Viestejä
1 210
Juu, tsekkasin nimenomaan logeista ja siellä tuo blokkaus näkyi.
Varsin mielenkiintoista. Ja varmaan ufw:n restart on tullut kokeiltua ?
Edit: sudo ufw status verbose antaa vähäsen lisää infoa tuohon statukseen, mutta en kyllä heti keksi, että mikä tuossa väärin voisi olla.
 
Liittynyt
07.01.2021
Viestejä
678
Tarkoitat varmaan reloadia? Juu.

Mutta sanoisin että kuuntelijat on:
Koodi:
$ sudo ss -l -t -u
Netid     State      Recv-Q     Send-Q                 Local Address:Port             Peer Address:Port     Process
udp       UNCONN     0          0                      127.0.0.53%lo:domain                0.0.0.0:*
udp       UNCONN     0          0                135.181.155.80%eth0:bootpc                0.0.0.0:*
tcp       LISTEN     0          4096                   127.0.0.53%lo:domain                0.0.0.0:*
tcp       LISTEN     0          128                          0.0.0.0:ssh                   0.0.0.0:*
tcp       LISTEN     0          511                          0.0.0.0:https                 0.0.0.0:*
tcp       LISTEN     0          80                         127.0.0.1:mysql                 0.0.0.0:*
tcp       LISTEN     0          511                          0.0.0.0:http                  0.0.0.0:*
tcp       LISTEN     0          128                             [::]:ssh                      [::]:*
tcp       LISTEN     0          511                             [::]:https                    [::]:*
tcp       LISTEN     0          511                             [::]:http                     [::]:*
Ei kun eikäs. Sain tuon 3000-portin toimimaan, piti palauttaa sääntö jonka ehdin näpätä pois. 5000-portti sen sijaan ei toimi ulospäin. Tosin eipä sen just nyt tarvitsekaan.
 

jad

Liittynyt
22.10.2016
Viestejä
1 210
Tarkoitat varmaan reloadia? Juu.

Mutta sanoisin että kuuntelijat on:
Koodi:
$ sudo ss -l -t -u
Netid     State      Recv-Q     Send-Q                 Local Address:Port             Peer Address:Port     Process
udp       UNCONN     0          0                      127.0.0.53%lo:domain                0.0.0.0:*
udp       UNCONN     0          0                135.181.155.80%eth0:bootpc                0.0.0.0:*
tcp       LISTEN     0          4096                   127.0.0.53%lo:domain                0.0.0.0:*
tcp       LISTEN     0          128                          0.0.0.0:ssh                   0.0.0.0:*
tcp       LISTEN     0          511                          0.0.0.0:https                 0.0.0.0:*
tcp       LISTEN     0          80                         127.0.0.1:mysql                 0.0.0.0:*
tcp       LISTEN     0          511                          0.0.0.0:http                  0.0.0.0:*
tcp       LISTEN     0          128                             [::]:ssh                      [::]:*
tcp       LISTEN     0          511                             [::]:https                    [::]:*
tcp       LISTEN     0          511                             [::]:http                     [::]:*
Njoo, reloadkin kelpaa, mutta itse olen ollut joskus menneisyydessä havaitsevinani ufw:n kanssa, että väkivaltainen restart hoitaa homman paremmin kotiin ja jäänyt tapa päälle :D

Tuossa listallahan ei ole mitään kuuntelemassa 3000 tai 5000 portteja.
 
Liittynyt
07.01.2021
Viestejä
678
Eäh, enhän minä tuolla serverillä mitään 5000-porttia edes tarvitse.

Mutta voiko React-sovelluksessa asettaa sisäisesti käytetyn kielen (locale) jotenkin? Tuo komponentti lajittelee nyt väärin, ja vika saattaa olla hyvinkin collationissa.
 
  • Tykkää
Reactions: jad
Liittynyt
07.01.2021
Viestejä
678
Oli muuten puute tuossa komponentissa. Nyt on korjattu. Ihan nopeaa toimintaa PrimeTekiltä vaikka en ole edes maksava asiakas.
 
Liittynyt
07.01.2021
Viestejä
678
Alkaa kyllä kohta järki lähteä kun yritän tuolla Flaskilla tehdä backendiä jossa sisään tulevien kenttien perusteella sortataan ja filtteröidään dataa. SQLAlchemyä ei selvästikään ole tähän hommaan suunniteltu, kun mitään ei pysty tekemään helposti ja koko ajan jokin vastustaa. Olisin jo raa'alla SQL:llä kirjoittanut tuon logiikan moneen kertaan, vaikka se karseaa nysväämistä onkin.

Nytkin tuo *#¤#) on päättänyt, että jos määrittelen ORM:ssa kentän hybrid_propertyksi ja yritän accessoida yhden relationshipin kenttää, niin se on joku vitun instrumentedjotain. Toisin kuin kaikissa muissa vastaavissa propertyissä, joissa accession myös relationshippejä. Siis tämä ei toimi:
Koodi:
    nationality = relationship(
        'Country', foreign_keys=[nationality_id], uselist=False, viewonly=True)

    @hybrid_property
    def nationalityname(self) -> Union[str, None]:
        if self.nationality:
            return self.nationality.name
        else:
            return None
Mutta tämä toimii:
Koodi:
    authors = relationship("Person",
                           secondary='join(Part, Contributor, Part.id == Contributor.part_id)',
                           primaryjoin='and_(Person.id == Contributor.person_id,\
                           Contributor.role_id == 1, Part.shortstory_id == ShortStory.id)',
                           uselist=True, order_by='Person.alt_name', viewonly=True,
                           foreign_keys=[Contributor.part_id, Contributor.person_id, Contributor.role_id])

    @hybrid_property
    def author_str(self) -> str:
        if self._author_str != '':
            return self._author_str
        if len(self.authors) > 0:
            self._author_str = ' & '.join([x.name for x in self.authors])
        return self._author_str
Tulos on
Koodi:
Exception has occurred: AttributeError       (note: full exception trace is shown but execution is paused at: nationalityname)
Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with Person.nationality has an attribute 'name'
Google ei ole auttanut, pari osumaa tuli mutta niissä on eri tilanne. Ainoa mitä keksin on se, että tuo automaattinen relationship tuottaa jostain täysin käsittämättömästä syystä erilaisen objektityypin, mutta ei sekään voi pitää paikkaansa, koska kyllä minä noitakin kenttiä nykyisen frontin puolella käytän.
 
Liittynyt
07.01.2021
Viestejä
678
SQLAlchemyn irc-kanavalla käydyn keskustelun pohjalta olen päätymässä siihen lopputulokseen, että tämän homman hoitaa ihan yhtä helposti raa'alla SQL:llä. Siis tyyliin
Koodi:
if column == 'name':
  if op == 'eq':
   sql  = sql + ' AND person.name = value'
 else if op == 'ne':
  sql = sql + ' AND person.name != value'
...
if column == 'dob':
  if op == 'eq':
...
Käytännössä ilmesesti saman joutuisi tekemään sqla:nkin kanssa, paitsi että nuo tehtäisiin ORM:lla.
 
Liittynyt
07.01.2021
Viestejä
678
Jaahas, hitaus johtuu Marshmallow-modulista. Se on _todella_ hidas. Onneksi on olemassa Lyftin tekemä toastedmarshmallow, joka lupaa nopeuttaa vähintään 10x tuota.

Paitsi että tuota modulia ei ole näköjään ylläpidetty sitten vuoden 2019 eikä toimi enää. Kiva huomata, kun on tunnin tuon kanssa tuskaillut.
 
Liittynyt
07.01.2021
Viestejä
678
En oikein keksi mikä olisi paras API-rakenne seuraavalle sivulle: Suomenkieliset SF-, Fantasia- ja Kauhukirjat

Pitäisikö olla yksi /people/<id> -endpoint, joka palauttaa ihan kaiken? Tietorakenne vaan on aika monimutkainen, kun tuossa on perustietojen (nimi, syntymäaika, kansallisuus, palkinnot ym) lisäksi
  • Teokset, joihin liittyy omia tietoja (nimi, alkup. julkaisuvuosi, genre ym) ja
    • Painokset, joihin liittyy omia tietoja (painoksen numero, painosvuosi), ja mm
      • Kustantaja, jolla on omia tietojaan (minimissään tarvitaan nimi ja id)
      • Novellit (eri painoksilla saattaa olla hieman eri novelleita) ja mahdollisesti artikkeleita (käytännössä yleensä esipuhe),
      • Kääntäjät ja toimittajat (vähintään nimi ja id tarvitaan).
Eli tulisi melkoinen tietorakenne. Mutta ei tarvittaisi kuin yksi kutsu. Vaihtoehto on tietysti luoda enemmän endpointteja ja tehdä useampi kutsu per sivu. Mutta ellei tässä mene ihan hurjaksi (kaikki painoksetkin haetaan erikseen), niin monimutkainen tämäkin on. Miten tämän tapainen on järkevin tehdä?
 
Liittynyt
07.01.2021
Viestejä
678
Ja minulla taitaa olla taas tilojen kanssa ongelmia, mutta miksei tässä esimerkissä checkboxiin tule ruksia kun sitä klikkaa? Tila selvästi vaihtuu kuitenkin.


Ei kun mitä ihmettä.. tuo toimii jos klikkaa tuota labelia (joka on jostain syystä väärässä paikassa), mutta vain satunnaisesti jos klikkaa itse laatikkoa.
 
Liittynyt
17.10.2016
Viestejä
14 550
@Makis, se "toimii aina" kun painat selvästi checkboxin oikealla puolella. Jos painat boxia, ei näytä juuri toimivan. En tunne tuota kirjastoa, jota käytät.
 
Liittynyt
07.01.2021
Viestejä
678
Nyt taas vähän ihmetyttää, kun olen tuijotellut tovin koodia ja en tajua miksi se ei tulosta mitään. works näyttää tältä:
Koodi:
{
  "Hoffmann, E. T. A.": [
    {
      author_str: "Hoffmann, E. T. A.",
      bookseriesnum: "",
      bookseriesorder: 0,
      descr_attr: null,
      description: null,
      editions: [
        {
          coll_info: "",
          coverimage: 1,
          dustcover: 1,
          editionnum: 1,
          id: 3453,
          images: [
          ],
          imported_string: "\n<b>Kissa Murr</b>. (Lebensansichten des Katerns Murr, 1820-22). Suom Teijo Havu. Oy Suomen Kirja 1946. [F].",
          isbn: "",
          misc: "Oy Suomen",
          pages: null,
          printedin: null,
          publisher: {
            description: null,
            fullname: "Valtion kustannusliike Oy Kirja",
            id: 397,
            image_attr: null,
            image_src: null,
            name: "Kirja",
          },
          pubseriesnum: null,
          pubyear: 1946,
          size: null,
          subtitle: "",
          title: "Kissa Murr",
          version: null,
        },
      ],
      id: 3014,
      imported_string: "\n<b>Kissa Murr</b>. (Lebensansichten des Katerns Murr, 1820-22). Suom Teijo Havu. Oy Suomen Kirja 1946. [F].",
      misc: "Oy Suomen",
      orig_title: "Lebensansichten des Katerns Murr",
      pubyear: 1820,
      subtitle: "",
      title: "Kissa Murr",
    },
  // Leikattu neljä taulukon arvoa pois
  ],
}
worksin rakenne on siis
Koodi:
let works: Record<string, IWork[]> = {};
Ja koodi joka ei suostu näyttämään mitään on tällainen:
Koodi:
            {works && Object.entries(works).
                sort((a, b) => a > b ? 1 : -1).map(([group, ws]) => {
                    <h3>{group}</h3>
                    {
                        ws.map((work: IWork) => (
                            <Work work={work} />
                        ))
                    }
                })}
Idea siis tuossa on se, että kirjoittajalla saattaa olla yhteiskirjoja muiden kanssa tai salanimellä kirjoitettuja kirjoja. Kirjat on ryhmitelty noiden mukaan. Mutta tuo koodi ei tulosta edes groupiin mitään.
 
Liittynyt
17.10.2016
Viestejä
14 550
@Makis
  1. Kun debuggaat tuollaista niin yksinkertaista. Heitä sorttaus helvettiin. Heitä kaikki muu helvettiin paitsi se että rendaat tuon groupin. Se helpottaa sua ymmärtämään missä kusee. Ja se helpottaa mua kun ei tarvitse kahlata niin paljon kamaa läpi :D Sitten lisäät palikka kerrallaan ja katsot, mikä rikkoo. Sama koskee tota inputtia. Tossa on 99,99% ihan irrelevanttia dataa.
  2. Sun pitää palauttaa jotain tuolta ulommasta mapista. Nyt sä et palauta sieltä yhtään mitään jolloin mitään ei tietenkään rendata.
  3. Sorttaukseen kannattaa harkita funktiota localeCompare. Eli .sort((a, b) => a.localeCompare(b)).
 
Liittynyt
07.01.2021
Viestejä
678
Siis eikö se ulomman mapin outputti ole tuossa [group, ws] -tuplessa? Kovasti editorikin väittää että ovat string ja IWork[]. Sortin poisto ei vaikuta asiaan

Tuo localCompare() muuten oli hyvä vinkki, olisi varmaan aika pian aiheuttanut päänvaivaa.

Mutta siis käsittääkseni tuo Object.entries(works).map pitäisi palauttaa nuo dictionaryn itemit yksi kerrallaan niin, että tuplessa on avain ja arvo. Tuossa oli muuten bugi, tuo vertailu ei olisi toiminut oikein, mutta tosiaan vaikka poistan koko sortin niin tulos ei muutu.

Minulla on codesandboxissa vastaavan näköinen koodi ja se toimii: xenodochial-faraday-iov1c5 - CodeSandbox

(Ihan koodin lopussa on samanlainen rakenne.)
 
Liittynyt
04.03.2017
Viestejä
282
Sinulla on tuon ulomman mapin nuolifunktion koodi lohkon ({...}) sisällä joten se ei palauta mitään ellet tee eksplisiittistä returnia. Sisemmässä ei ole lohkoa joten siinä returni on implisiittinen. Codesandbox esimerkissäsi ei ole lohkoa kummassakaan mapissa joten se toimii odotetulla tavalla.
 
Liittynyt
17.10.2016
Viestejä
14 550
Siis eikö se ulomman mapin outputti ole tuossa [group, ws] -tuplessa?
map() toimii oikein vain jos palautat sieltä jotain. Sulla pitää olla siis return-lauseke siellä. Ja tähän lisähuomio, että nuolifunktiossa on implisiittinen return, jos käytät sen lyhyttä muotoa (eli ilman aaltosulkeita). Tuossa viestissäsi on aaltosulkeet eli nuolifunktiossa on ihan oma koodiblokkinsa, jolloin sulla on pakko olla siellä return jotta se tekee sen mäppäyksen oikein. Se puuttuu, joten koodi ei toimi.

Koodi:
const foobar = foo.map(x => <h3>x.bar</h3>); // OK, implisiittinen return

const foobar = foo.map(x => {
  return <h3>x.bar</h3> // OK, eksplisiittinen return
});
Sortin poisto ei vaikuta asiaan
Koodin yksinkertaistaminen vaikuttaa kahteen asiaan. 1. löydät ihan itse ne bugisi. 2. Me muut löydämme nopeammin ne bugisi. Pyri siis minimaaliseen hajoavaan esimerkkiin:

 
Liittynyt
07.01.2021
Viestejä
678
Okei, tuo map():n ominaisuus ei ollut tiedossa.

Koodin yksinkertaistaminen ei olisi auttanut, koska en olisi älynnyt noita aaltosulkuja poistaa kuitenkaan / en olisi edelleenkään tajunnut että aaltosulut on se ongelma. Minulla kun on C:ssäkin tapana laittaa aaltosulut yksittäisenkin operaation ympärille, siis esimerkiksi:
Koodi:
for(i=i;i<10;i++) {
  doobedoo(i);
}
Tuo on osa defensiivistä ohjelmointia. On joskus käynyt niin, että olen lisännyt tuollaiseen rivin kun aaltosulut on puuttuneet ja ihmetellyt sitten bugia. Olen myös pari kertaa korjannut jonkun muun tekemänä saman bugin. Ainoa poikkeus on jos operaatio tulee samalle riville (esim. terniäärioperaattori).
 
Liittynyt
17.10.2016
Viestejä
14 550
Koodin yksinkertaistaminen ei olisi auttanut, koska en olisi älynnyt noita aaltosulkuja poistaa kuitenkaan / en olisi edelleenkään tajunnut että aaltosulut on se ongelma.
Kuten kirjoitin jo 2 kertaa, se auttaa muita ratkaisemaan sun ongelmasi kun et tuo tänne pitkiä koodinpätkiä vaan minimaalisia. Jos ei muuta, niin se on kohteliasta.
 
Liittynyt
07.01.2021
Viestejä
678
Minun esimerkkissäni oli 5 riviä koodia, en ajattelut että se olisi liian pitkä... tai oikeastaan varsinaista koodia on 3 riviä.
 
Liittynyt
17.10.2016
Viestejä
14 550
Minun esimerkkissäni oli 5 riviä koodia, en ajattelut että se olisi liian pitkä... tai oikeastaan varsinaista koodia on 3 riviä.
Ei toi vänkääminen tee asiasta yhtään sen järkevämpää. Sulla oli myös muutamakymmentä riviä inputtia, jonka olisi voinut typistää minimiin. Yhä edelleen, kannattaa sisäistää tämä:

In computing, a minimal reproducible example (abbreviated MRE) is a collection of source code and other data files which allow a bug or problem to be demonstrated and reproduced. The important feature of a minimal reproducible example is that it is as small and as simple as possible, such that it is just sufficient to demonstrate the problem, but without any additional complexity or dependencies which will make resolution harder.

Ja tämä ei suinkaan ole ensimmäinen kerta kun sun koodiesimerkeissä on ihan tajuton määrä tavaraa, mikä ei liity mitenkään käsillä olevaan ongelmaan.
 
Liittynyt
07.01.2021
Viestejä
678
Tällaista etusivua olen vähän hahmotellut. Ihan en ole tyytyväinen, mutta en osaa sanoa, että mitä pitäisi parantaa. Kenelläkään antaa vinkkejä?

 
Liittynyt
06.11.2016
Viestejä
1 750
Tällaista etusivua olen vähän hahmotellut. Ihan en ole tyytyväinen, mutta en osaa sanoa, että mitä pitäisi parantaa. Kenelläkään antaa vinkkejä?

Ottaisin tuon Sf-bibliografia otsikon kokonaan pois. Tuo SuomiSF-teksti on liian lähellä noita navigaation linkkejä ja nuo alhaalla olevat kortit vaatii lisää paddingiä ympärilleen.
 
Liittynyt
07.01.2021
Viestejä
678
Tuon SuomiSF-tekstin olisi siis tarkoitus olla jonkunlainen kuva/logo.

Mutta totta, tuon otsikon poistaminen paransi kyllä ulkoasua.
 
Liittynyt
17.10.2016
Viestejä
14 550
Tuon SuomiSF-tekstin olisi siis tarkoitus olla jonkunlainen kuva/logo.
Nyt ehkä vähän hassusti Share ja imgur ovat isoimmat tekstit leiskassa. SuomiSF voisi olla isoin elementti (ja ehkä tuo pelkkä sininen tausta tekstille on vähän kökkö. Menupalkki voisi olla ihan vaan yläreunassa, ellei tuohon tyhjään valkoiseen tilaan ole tarkoitus tulla jotain sisältöä.

Ja mihin tuo Share liittyy? Linkin jakamiseen tuo lienee täysin turha. Sen voi tehdä kopioimalla Urlin. Samoin imgurin mainostaminen lienee tarpeetonta?

Lopuksi: toimiiko tuo miten mobiililla? Mobile first on nykyään hyvä tapa tehdä sivuja. Eipä pääse unohtumaan potentiaalinen käyttäjäkunta.
 
Liittynyt
07.01.2021
Viestejä
678
Share ja imgur tulevat tuolta imgurista mukaan. Avaa tuo linkki niin näet pelkän kuvan.

Mobiilia en nyt ole vielä miettinyt. Mutta eiköhän tuo saa toimimaan kun vaikka jättää tuon kuvan pois + tekee tuosta uusimpien lisäämisestä ja tilastoista gridit.
 
Toggle Sidebar

Statistiikka

Viestiketjut
237 526
Viestejä
4 165 499
Jäsenet
70 420
Uusin jäsen
TuplaT

Hinta.fi

Ylös Bottom