-1

I have this function:

async geraQuiz(idEstudante) {
  let idioma = new Array()
  let livrosUnidadesGerarQuiz = new Array()
  const idsClassesEstudante = await this.getIdClassesEstudante(idEstudante) // Here i have this array return: [2,3]

  for(let i=0;i<idsClassesEstudante.length;i++){
   livrosUnidadesGerarQuiz = new Array() // Clear the array
   idioma.push(await this.getDadosClasseIdiomaEstudante(idsClassesEstudante[i]))
   livrosUnidadesGerarQuiz = await this.getLivrosUnidadesGerarQuiz(idsClassesEstudante[i], idBookClasseEstudante[0], qtdQuizGerar)
   idioma[i].quiz = livrosUnidadesGerarQuiz

   console.log(JSON.stringify(idioma))

   console.log(idioma[i].quiz[0])

   ...

In the console.log(idioma) i have this array of objects:

[
  {
    "id": 2,
    "code": "ING-NOT-2019",
    "description": "Inglês Noturno 2019",
    "start_date": "2019-12-30T03:00:00.000Z",
    "end_date": "2019-12-31T03:00:00.000Z",
    "period": "Noturno",
    "language": "Inglês",
    "status": false,
    "user_id": 1,
    "created_at": "2019-12-30 10:04:47",
    "updated_at": "2020-01-05 16:08:00",
    "language_substring": "US",
    "quiz": [
      {
        "id": 1,
        "class_id": 2,
        "book_unit_id": 1,
        "book_id": 1,
        "start_date": "2020-01-03T03:00:00.000Z",
        "end_date": "2020-01-15T03:00:00.000Z",
        "book_unit_sequence": 1,
        "status": false,
        "user_id": 1,
        "created_at": "2019-12-27T11:11:21.000Z",
        "updated_at": "2019-12-30T17:54:12.000Z",
        "unit": 1,
        "sequence": 1,
        "description": "UNIT_01_GRAMMAR",
        "qt_question": 5,
        "miniature": null
      },
      {
        "id": 2,
        "class_id": 2,
        "book_unit_id": 2,
        "book_id": 1,
        "start_date": "2020-01-15T03:00:00.000Z",
        "end_date": "2020-01-31T03:00:00.000Z",
        "book_unit_sequence": 2,
        "status": false,
        "user_id": 1,
        "created_at": "2019-12-27T11:11:39.000Z",
        "updated_at": "2019-12-27T11:11:39.000Z",
        "unit": 1,
        "sequence": 2,
        "description": "UNIT_01_VOCABULARY",
        "qt_question": 5,
        "miniature": null
      },
      {
        "id": 3,
        "class_id": 2,
        "book_unit_id": 3,
        "book_id": 1,
        "start_date": "2020-01-31T03:00:00.000Z",
        "end_date": null,
        "book_unit_sequence": 1,
        "status": false,
        "user_id": 1,
        "created_at": "2019-12-27T11:11:46.000Z",
        "updated_at": "2019-12-27T11:11:46.000Z",
        "unit": 2,
        "sequence": 1,
        "description": "UNIT_02_GRAMMAR",
        "qt_question": 5,
        "miniature": null
      }
    ]
  }
]

But when i try to acess the property with: console.log(idioma[i].quiz[0] i receive undefined, but the console.log() shows that i have this property quiz and is not undefined, why this is happening?

I put a return after the console.log(idioma[i].quiz[0]) to prevent that is not subscribing but i have the same result; and

I put one console.log(i) and i have the value 0

@Edit

the console.log(idioma) without stringify:

[
  Class {
    __setters__: [
      '$attributes',
      '$persisted',
      'primaryKeyValue',
      '$originalAttributes',
      '$relations',
      '$sideLoaded',
      '$parent',
      '$frozen',
      '$visible',
      '$hidden'
    ],
    '$attributes': {
      id: 2,
      code: 'ING-NOT-2019',
      description: 'Inglês Noturno 2019',
      start_date: 2019-12-30T03:00:00.000Z,
      end_date: 2019-12-31T03:00:00.000Z,
      period: 'Noturno',
      language: 'Inglês',
      status: false,
      user_id: 1,
      created_at: 2019-12-30T13:04:47.000Z,
      updated_at: 2020-01-05T19:08:00.000Z,
      language_substring: 'US',
      quiz: [Array]
    },
    '$persisted': true,
    '$originalAttributes': {
      id: 2,
      code: 'ING-NOT-2019',
      description: 'Inglês Noturno 2019',
      start_date: 2019-12-30T03:00:00.000Z,
      end_date: 2019-12-31T03:00:00.000Z,
      period: 'Noturno',
      language: 'Inglês',
      status: false,
      user_id: 1,
      created_at: 2019-12-30T13:04:47.000Z,
      updated_at: 2020-01-05T19:08:00.000Z,
      language_substring: 'US'
    },
    '$relations': {},
    '$sideLoaded': {},
    '$parent': null,
    '$frozen': false,
    '$visible': undefined,
    '$hidden': undefined
  }
]
bla
  • 995
  • 3
  • 11
  • 44
  • 1
    Unrelated to your question that I am still trying to look at, but just so you are aware, the best practice for declaring arrays is to use `const` over `let` unless you have to reassign the actual variable and to declare them using the array literal syntax over the Array constructor, just like this `const myArray = []` Here is a short explanation for some of the reasons why: https://www.mattlunn.me.uk/blog/2012/04/the-use-of-literals-vs-constructors/. Another best practice is to cache your array length in loops like this: `for (let i = 0, len = array.length; i < len; ++i) {...}. – Stephen M Irving Jan 08 '20 at 18:42
  • 1
    Try to console.log the **idioma** array without the `JSON.stringify` please. – Pedro Mutter Jan 08 '20 at 19:10
  • @Stephen Thanks, i change to const the variables that i don't will be reassign – bla Jan 08 '20 at 19:20
  • @Pedro Mutter please check my update question, i put the console.log() without the stringify – bla Jan 08 '20 at 19:20
  • When you are looking at this progressively, at what point in the flow does it become undefined? is it the key accessing, or the index accessing which kills it? – Fallenreaper Jan 08 '20 at 19:25
  • Thanks! Can you post now the class? That one that contains `quiz` attribute. – Pedro Mutter Jan 08 '20 at 19:25
  • @Fallenreaper in the acess of the index example: console.log(idioma[0].quiz[0] – bla Jan 08 '20 at 19:30
  • In idioma, if i put a json.parse(json.stringify) everything works well, i think is something in the vanilla serialization javascript? idioma.push(JSON.parse(JSON.stringify(await this.getDadosClasseIdiomaEstudante(idsClassesEstudante[i])))) – bla Jan 08 '20 at 19:31
  • 1
    Probably it is something with the quiz accessor... I need to see the class implementation to make sure. When you use JSON.stringify and JSON.parse, you are turning it in a plain JS object, that's why you access it normally – Pedro Mutter Jan 08 '20 at 19:37
  • It sounds like you may be inaccurately serializing. Check those files, but also check the runtime type of quiz and see what it is... if it is an array, and how many indices exist. – Fallenreaper Jan 08 '20 at 19:38
  • @Pedro Mutter this class is the result of one lucid models query of the framework adonis: async getDadosClasseIdiomaEstudante(idClasse){ return await Class .query() .where('id', idClasse) .first() } so, this function returns the model that i put in the edit of this question – bla Jan 08 '20 at 19:44

1 Answers1

1

I investigated throughout the Adonisjs framework source code and found this on the BaseModel class definition. It returns a proxy, and inside the proxy, he can trap the get and the set of the attributes and do many things that you don't need necessarily to know to use the framework.

My advice is to avoid this:

idioma[i].quiz = livrosUnidadesGerarQuiz

This way you are triggering the set trap of the BaseModel and doing things that you don't needed.

Try to keep things separately, like this:

const idiomas = [];

...

const quiz = await this.getLivrosUnidadesGerarQuiz(idsClassesEstudante[i], idBookClasseEstudante[0], qtdQuizGerar);
const idioma = await this.getDadosClasseIdiomaEstudante(idsClassesEstudante[i])'
idiomas.push({ quiz, idioma });

...

This way you won't have accessor or serialization problems related to it, and you know that always idiomas[i].idioma is the model class.

Pedro Mutter
  • 1,178
  • 1
  • 13
  • 18