mwhib
mwhib

Reputation: 113

Map json to dart objects

I'm looking for some direction on mapping json to an object. I'm trying to use live data from a web api. When I run the code I get the following error: Class '_LinkedHashMap' has no instance getter 'iterator'.

Here's what I'm trying to do:

import 'package:angular/angular.dart';
import 'dart:convert';


@NgController(
    selector: '[movies]',
    publishAs:  'ctrl'
)
class MoviesController {

  //  vars
  bool moviesLoaded = false;
  String nameToSearch = 'life';
  Http _http;
  List<MovieBrief> movies = [];

//  constructor
  MoviesController( Http this._http ) {
    _loadData();
  }

//  functions
  void _loadData() {
    moviesLoaded = false;

//  _http.get('http://www.omdbapi.com/?s=' + nameToSearch)
    _http.get('movies_briefs.json')
    .then((HttpResponse response) {

      for (Map mb in response.data) {
        movies.add(new MovieBrief.fromJsonMap(mb));
      }

      moviesLoaded = true;
    },
    onError: (Object obj) {
        print(obj);
      }
    );
  }
}

class MovieBrief {
  String title;
  String year;
  String imdbId;
  String type;

  MovieBrief(this.title, this.year, this.imdbId, this.type);

  String toJsonString() {
    Map data = {"Search": [
        {
            "Title" : title,
            "Year" : year,
            "imdbID" : imdbId,
            "Type" : type
        }]};
    return JSON.encode(data);
  }

  factory MovieBrief.fromJsonMap( Map json ) {
    return new MovieBrief( json['Title'], json['Year'], json['imdbID'], json['Type']);
  }
}

Here's a sample of the json results returned by the web api:

{
    "Search": [
        {
            "Title": "Life of Pi",
            "Year": "2012",
            "imdbID": "tt0454876",
            "Type": "movie"
        },
        {
            "Title": "Life Is Beautiful",
            "Year": "1997",
            "imdbID": "tt0118799",
            "Type": "movie"
        },
        {
            "Title": "Life of Brian",
            "Year": "1979",
            "imdbID": "tt0079470",
            "Type": "movie"
        },
        {
            "Title": "It's a Wonderful Life",
            "Year": "1946",
            "imdbID": "tt0038650",
            "Type": "movie"
        },
        {
            "Title": "A Bug's Life",
            "Year": "1998",
            "imdbID": "tt0120623",
            "Type": "movie"
        },
        {
            "Title": "A Bug's Life",
            "Year": "1998",
            "imdbID": "tt0174716",
            "Type": "movie"
        },
        {
            "Title": "The Tree of Life",
            "Year": "2011",
            "imdbID": "tt0478304",
            "Type": "movie"
        },
        {
            "Title": "The Life Aquatic with Steve Zissou",
            "Year": "2004",
            "imdbID": "tt0362270",
            "Type": "movie"
        },
        {
            "Title": "Lara Croft Tomb Raider: The Cradle of Life",
            "Year": "2003",
            "imdbID": "tt0325703",
            "Type": "movie"
        },
        {
            "Title": "Dan in Real Life",
            "Year": "2007",
            "imdbID": "tt0480242",
            "Type": "movie"
        }
    ]
}

Upvotes: 3

Views: 1313

Answers (2)

Alan Knight
Alan Knight

Reputation: 2971

I'm guessing response.data is a map, so you can't iterate on it with a for loop. You need to either use response.data.keys, response.data.values, or use the forEach method on the map, which provides both.

  response.data.forEach((key, value) => movies.add(Etc)

As per the other response, something like json_object is also worth looking into, but that's a way of avoiding hard coding the field mappings.

Upvotes: 0

user2685314
user2685314

Reputation: 1069

Have you looked at the json_object package? This parses a json string and creates properties on the resulting object, in your case you would have say film.title, film.year etc. You can store each json_object in a list.

Upvotes: 1

Related Questions