topu
topu

Reputation: 25

How do I load an object object from a Future class into another object/class?

I have two Futures which load a String from a JSON File for me. My Goal is to have a class Data within which, I can hold different objects (for example Feed). What I don't understand right now, is how I write a class data which can hold the object feed, as well as, load the feed object from the Future.

import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
import 'dart:convert';
import 'package:freeletics_insights/feed.dart';


Future<String> _loadFeedAsset() async {
  return await rootBundle.loadString('assets/json/userfeed1.json');
}

Future<Feed> loadFeed() async {
  String jsonFeed = await _loadFeedAsset();
  final jsonResponse = json.decode(jsonFeed);
  Feed feed = new Feed.fromJson(jsonResponse);
  //print(feed.feedEntries.length);
  return feed;
}


class Data {
  Feed feed;

  Data.loadData(){
    this.feed = loadFeed();
  }
}

void main{
  var data = Data.loadData();
  print(data.feed.feedEntries.length);
}

I alway get an error that the type FutureFeed cannot be assigned to a type Feed.

Upvotes: 1

Views: 2781

Answers (1)

Tom Alabaster
Tom Alabaster

Reputation: 985

This is something that used to slip me up a bit when I first started using Dart and Flutter. Your loadFeed() method returns a type of Future<Feed> but your Data classes member feed is of type Feed, which are two different types. What you want to do is "unwrap" the Future<Feed> returned from your loadFeed() method in order to access the Feed object.

You "unwrap" Future objects using the async/await syntax.

What it might look like you can do is:

class Data {
  Feed feed;

  Data.loadData() async {
    this.feed = await loadFeed();
  }
}

... but you loadData() is a constructor of Data and you can't have constructor methods marked as async. You can however mark you main() method as async to use async/await syntax to unwrap your Future<Feed>.

The only thing I've changed in your code is added your feed member of Data to the constructor and adapted your main() method to asyncronously load your feed and pass the result into the constructor of your Data object.

Future<String> _loadFeedAsset() async {
  return await rootBundle.loadString('assets/json/userfeed1.json');
}

Future<Feed> loadFeed() async {
  String jsonFeed = await _loadFeedAsset();
  final jsonResponse = json.decode(jsonFeed);
  Feed feed = new Feed.fromJson(jsonResponse);
  //print(feed.feedEntries.length);
  return feed;
}


class Data {
  Feed feed;

  Data(this.feed);
}

void main async {
  var feed = await loadFeed();
  var data = Data(feed);
  print(data.feed.feedEntries.length);
}

Upvotes: 1

Related Questions