8768 sujets

Développement web côté serveur, CMS

Bonjour,

Sous Node.js j'arrive à récupérer un objet de calendrier et à le passer à mon objet de rendu de page ("data") de cette manière (je simplifie) :
data._calendar = liturgicalCalendar(DateTime.fromFormat(day + month + year, 'ddMMyyyy'), 'france')

Ce qui me donne ceci comme objet :
{
  p: { key: 'lent', name: 'Carême', color: 'purple', priority: 9 },
  f: {
    key: 'defaultKey',
    name: 'De la férie',
    extra: '',
    color: '',
    type: '',
    priority: 13
  },
  m: {
    key: 'secondLentSunday',
    name: 'Deuxième dimanche de Carême, <em>Reminiscere</em>',
    color: 'purple',
    type: 1,
    priority: 2
  },
  key: 'secondLentSunday',
  name: 'Deuxième dimanche de Carême, <em>Reminiscere</em>',
  extra: '',
  fullName: 'Deuxième dimanche de Carême, <em>Reminiscere</em>',
  link: '',
  color: [ 'purple', 'purple' ],
  type: 'solennité',
  priority: 2,
  date: '28/02/2021',
  weekday: 7
}

Jusque là tout va bien, c'est ce qui est attendu. Mais lorsque je cherche à itérer sur tous les jours du mois afin d'avoir toutes les infos du mois en cours, rien ne va plus :
{
    '1': {
    // @note retourne les objets du 1 au 27 février...
  },
    '28': {
      p: [Object],
      f: [Object],
      m: [Object],
      key: 'secondLentSunday',
      name: 'Deuxième dimanche de Carême, <em>Reminiscere</em>',
      extra: '',
      fullName: 'Deuxième dimanche de Carême, <em>Reminiscere</em>',
      link: '',
      color: [Array],
      type: 'Solennité',
      priority: 2,
      date: '28/02/2021',
      weekday: 7
    }
  }

Comme vous le voyez, les objects et tableaux de second niveau sont renvoyés non interprétés, sous forme de [Object] et [Array]. Pour arriver à ce résultat non souhaité j'ai fais comme ceci (attention, ça va certainement vous piquer les yeux) :
    const dateTest = DateTime.fromFormat(month + year, 'MMyyyy')
    const daysInMonth = dateTest.daysInMonth
    const calendarItem = {}
    for (let i = 1; i < daysInMonth + 1; i++) {
      calendarItem[i] = liturgicalCalendar(dateTest.plus({days: i - 1}))
    }
    data._calendar = calendarItem

Pour ma fonction de calendrier j'avais pourtant écrit un test pour vérifier, et lui fonctionnait comme attendu :
const test0 = (() => { // @todo For test.
  const dayMonthYear = '28022021'
  const dateTest = DateTime.fromFormat(dayMonthYear, 'ddMMyyyy')
  const daysInMonth = dateTest.daysInMonth
  for (let i = 1; i < daysInMonth; i++) {
    const lc = liturgicalCalendar(dateTest.plus({days: i}))
    console.log(lc) // retourne tous les objets dans leur intégralité
  }
})()

Il semble que le passage dans la boucle, sous forme de tableau, soit un problème. Il y a forcément un truc que je n'ai pas compris, mais il y a tellement de notions que je ne maîtrise pas que je ne sais où intervenir. Merci pour vos remarques et suggestions.
Modifié par Olivier C (20 Jan 2021 - 06:17)
Modérateur
Bonjour,

Ça part dans tous les sens ! Smiley cligne

Je n'arrive pas à reproduire ton affichage (les [Object] et [Array]).

1) Quand tu dis "Mais lorsque je cherche à itérer sur tous les jours du mois afin d'avoir toutes les infos du mois en cours, rien ne va plus", comment affiches-tu le contenu de l'objet ci-dessous pour obtenir tes [Object] ? Via la console côté client ? Via un JSON.stringify() ?
{
    '1': {
    //...
  },
    '28': {
      p: [Object],
      f: [Object],
      m: [Object],
      //...
    }
  }

2) Petit détail juste en passant, pour remplir ton calendarItem, tu utilises une boucle avec un indice entier, donc a priori on s'attend à ce que tu remplisses un tableau, mais calendarItem est déclaré avec {} au lieu de []. Ça marche parce que javascript fait les transformations qui vont bien automatiquement, mais ça ne me semble pas très cohérent et plutôt une mauvaise pratique.

Quand tu écris calendarItem[1]=..., si tu as déclaré calendarItem avec [], l'indice restera un entier en mémoire, mais si tu as déclaré calendarItem avec {}, l'indice est transformé par javascript en une chaine de caractère qui sera donc ici "1".

Amicalement,
Bonjour parsimonhi,

L'objet est correct et est renvoyé par la fonction liturgicalCalendar() que tu m'a vu élaborer sur ce forum. Les résultats que je montre sont récupérés à partir de la console côté serveur. La boucle for est placée dans mon modèle (j'ai fait une séparation MVC pour Express.js).
Modérateur
Bonjour,

Ça me parait bizarre, cette histoire.

Quel outil te permet de voir cette console côté serveur ? Quel est le système d'exploitation côté serveur ?

Que dit la console côté client si on fait un console(data) à la réception de l'objet data (et avec quel navigateur) ?

Amicalement,
Je suis sous Node.js, plus spécifiquement Express, et je sors les résultats avec un console.log.

Le contrôleur fait un res.render() avec le moteur pug plutôt qu'un res.send() (ce sont des fonctions Express), du coup il n'y a pas d'objet data côté client.
Modifié par Olivier C (20 Jan 2021 - 09:12)
Modérateur
Bonjour,

Oui, mais tu le vois où, le résultat de ton console.log ? Comment tu vois ce que t'as mis dans la console ? En regardant dans le terminal du serveur ? Ou bien tu rediriges vers un fichier ?

EDIT: et ton serveur c'est quoi ? un serveur de production sous linux ? ou bien tu fais juste des tests sur un PC ?

Amicalement,
Modifié par parsimonhi (20 Jan 2021 - 09:23)
Je regarde dans le terminal du serveur. Pour l"instant tout le code est un prototype en local sur Ubuntu 19.10.
Modérateur
Bonjour,

Tu n'aurais pas fait par hasard un
console.log(data._calendar.toString());


Il faut faire soit
console.log(data._calendar));

ou bien
console.log(JSON.stringify(data._calendar));


Amicalement,
Merci parcimonhi, j'utilise :
console.log(data))

Ou :
console.log(data._calendar))

C'est bien un objet qui doit être retourné, et non du JSON. Je conçois qu'il est très difficile d'aider dans ces conditions étant donné que le code est côté backend. Je pense que je vais finir par mettre mon repository en mode public. Je ne suis pas la NASA et ça sera quand même plus simple...
Modifié par Olivier C (20 Jan 2021 - 13:11)
Modérateur
Bonjour,

C'est vrai que c'est un peu devinette, là. Le problème peut venir de n'importe où, et a priori pas du code que tu as déjà donné (ceci dit je peux me tromper aussi).

Amicalement,
Moi je pense que le problème vient de ce code, car dans le premier exemple (pour une seule journée) ça marche.

Mais tu as raison de dire que "ça part dans tous les sens". Je vais isoler mon problème et reposer la question de manière plus concise, sans tout l'environnement Node.js.
Un p'tit retour plus d'un an après... mieux vaux tard que jamais :
Dans mon framework Express je faisais ceci pour préparer le rendu :
res.render('monTemplate', data)

Ce qui me renvoyait des objets annonymes mais dont je pouvais appeler directement les propriété comme des variables :
//- avec pugjs comme moteur de template :
p= _full_name

Le problème était que mes objets s'écrasaient car appelés les uns à la suite des autres, seul le dernier était pris en compte à l'appel d'une variable. Or il fallait que je trouve un moyen d'iterer dessus dans mes vues...
En définitive j'ai "affecté" (sans doute pas le bon terme) les objets à une variable `data` afin de pouvoir itérer dessus :
res.render('monTemplate', { data: data })

La même chose en moins explicite mais plus concis :
res.render('monTemplate', {data})

Et j'ai enfin pu itérer dans mes vues :
//- pugjs :
each e, i in data
  li
    a(href='/person/' + e._id) #{e._full_name}

Modifié par Olivier C (15 Feb 2022 - 23:58)
Meilleure solution