Por qué no puedo hacer referencia a una clave en un objeto que ya está colocado en la clave de otro objeto mientras se asigna de esta manera:

var object = {
  "allStudents": [
    {
      "name": "John",
      "hobbies": {
        "sport": "Football",
        "music": "Piano"
      } ,
    },
    {
      "name": "Julyo",
      "hobbies": {
        "sport": "Vollyball",
        "music": "Guitar"
      } ,
    },
  ],
};

class Student {
  String name;
  dynamic hobbies;
  Student({this.name, this.hobbies});
}

class Hobbies {
  String sport;
  String music;
  Hobbies({this.sport, this.music});
}

List<Student> studentsList = [];

void getStudentsList () {
  studentsList = object["allStudents"].map((stu)=>
  Student(
    name: stu["name"] ,
    hobbies: Hobbies(
      sport: stu['hobbies']['sport'] ,
        music:stu['hobbies']['music'],
    ) ,
  )
  ).toList();
}

Todo funciona muy bien hasta que agregue el segundo operador ['sport'] o ['music'] como el IDE sigue diciéndome:

El operador '[]' no está definido para la clase 'Objeto'. Intente definir el operador '[]'.

Ver captura de pantalla: no puede hacer referencia al valor de una clave en la clave de otro objeto

2
ahmad 18 feb. 2020 a las 20:35

2 respuestas

La mejor respuesta

Dart no es consciente de cómo es su estructura, por lo tanto, debe hacerlo al proporcionar un yeso.

void getStudentsList () {
  studentsList = (object["allStudents"] as List<Map<String,dynamic>>)
      .map((stu)=>
  Student(
    name: stu["name"] ,
    hobbies: Hobbies(
      sport: stu['hobbies']['sport'] ,
        music:stu['hobbies']['music'],
    ) ,
  )
  ).toList();
}

Lo probé en este borrador de DartPad y funcionó ... https://dartpad.dev/b338f2a46bcb361de5e05c5ea6b8c74f

1
lordvidex 18 feb. 2020 a las 18:06

Esto se debe a que su var object es del tipo Map<String,Object>, y cuando accede al uso primero de [] , tiene Object como retorno, pronto el Objeto no es un map o iterable, el segundo [] no se puede aplicar. Debe indicar explícitamente que su object es del tipo Map<String, dynamic>, como en el siguiente ejemplo:

Map<String, dynamic> object = {
  "allStudents": [
    {
      "name": "John",
      "hobbies": {"sport": "Football", "music": "Piano"},
    },
    {
      "name": "Julyo",
      "hobbies": {"sport": "Vollyball", "music": "Guitar"},
    },
  ],
};

Y cambie su código de análisis a un mapa explícito para trabajar con el segundo []:

void getStudentsList() {
    final test = (object["allStudents"] as List)
        .map<Student>(
          (stu) => Student(
            name: stu["name"],
            hobbies: Hobbies(
              sport: stu['hobbies']['sport'],
              music: stu['hobbies']['music'],
            ),
          ),
        )
        .toList();

    print(test);
  }

¡Ahora funciona!

Nota: Dinámico puede ser cualquier tipo de valor posible, diferente del tipo Object, para más información, vea la discusión ¿Cuál es la diferencia entre dinámico y objeto en dardo?

2
Renê Guilherme Nucci 18 feb. 2020 a las 18:06