1

I am getting the referer for a header with a Future function and then I am trying to pass that to a build widget:

referer() async {
   refererFinal = await getReferer();
}

Map<String, String> loadHeaders() {
    Map<String, String> headers = new Map();
    headers['Referer'] = refererFinal!;
    return headers;
}


Image.network(URI,
   headers:loadHeaders(),
   errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) {
      return Image.asset(defaultImage);
   }
)

The problem is, referer() function loads after the build tree, so my headers remain blank.

How can I fix this?

UPDATE

This is my getReferer() method:

static Future<String?> getReferer() async {
   return headers!['referer'];
}
BradG
  • 673
  • 1
  • 14
  • 26
  • 1
    Does this answer your question? [What is a Future and how do I use it?](https://stackoverflow.com/questions/63017280/what-is-a-future-and-how-do-i-use-it) – nvoigt Mar 19 '23 at 09:28
  • This is a good one indeed, thank you for the comment! Unfortunately, I couldn't get this to work as desired. – BradG Mar 19 '23 at 21:28

2 Answers2

3

You can wrap your image with FutureBuilder to build the widget once the referer() function completes.

Future<String?> referer() async {
   return await getReferer();
}

FutureBuilder(
    future: referer(),
    builder: (BuildContext context, AsyncSnapshot<String?> snapshot) {
      if (snapshot.connectionState == ConnectionState.done) {
        var referer = snapshot.data!;
        return Image.network(
          URI,
          headers: {'Referer': referer},
          errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) {
            return Image.asset(defaultImage);
          },
        );
      } else {
        // Do something, maybe show a progress bar that it's loading
        // but you need to return a widget.
      }
    },
);
Almis
  • 3,684
  • 2
  • 28
  • 58
  • My problem is that `referer()` is an async function getting its value from `getReferer()` which is Future, hence the `async` and `await` in it. With `FutureBuilder`, I get this error: `type 'Future' is not a subtype of type 'Future?'` in reference to `future: referer()` and I have been trying to fix it all day. – BradG Mar 18 '23 at 23:15
  • I have edited my answer. The `referer()` method needs to return a Future then and `AsyncSnapshot` becomes `AsyncSnapshot`. Also, I used ` var referer = snapshot.data!;` because it's nullable you better handle it as you want. – Almis Mar 18 '23 at 23:32
  • Thank you for the updated answer! This is really weird, now what happens is `getReferer()` prints, then `referer()` prints and then I get Error: `Null check operator used on a null value` for `var referer = snapshot.data!;`, i.e. `snapshot.data` is null but how can it be? – BradG Mar 19 '23 at 08:30
  • that depends on the `getReferer` method I cannot tell you what is wrong there without looking at the code. – Almis Mar 19 '23 at 14:31
  • I finally managed to fix that by passing the Referer to the preferences, right after user login. Fixed my problem but not what's wrong with the code above. I made an update with the `getReferer()` for reference. – BradG Mar 19 '23 at 21:25
0

You can either check this manually with a bool variable and then display an empty container or similar if the headers have not been loaded yet.

Or you can use the FutureBuilder widget created by Flutter, which was made especially for this purpose:

https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

Ozan Taskiran
  • 2,922
  • 1
  • 13
  • 23