Home > Back-end >  How to prevent making more URL request after an image is already downloaded via Internet?
How to prevent making more URL request after an image is already downloaded via Internet?

Time:10-15

var alreadyDdl = false; 
getLogoUrl(context) async {
  if(!alreadyDdl) {
      final db = Localstore.instance;
      final data = db.collection('inputs').doc("1").get();
      var database = (await data)["content"].toString();
      var form = new DGForm("project/getwebsitelogo", {"database": database});
      var ret = await form.urlGET(context);
      ResponseObject responseObject =
      ResponseObject.fromJson(json.decode(ret.body));
      print("hola");
      var hola = (responseObject.datas[0][0].toString());
      bandeauDuClient = hola;
      print(hola);
      return hola;
   }
}
getLogoUrl(context).then((val) {
    setState(() => 
       logoUrl = val
    );
    alreadyDdl = true;
});

Will never display me the server downloaded image in the widget build

(logoUrl != null) ? Image.network(logoUrl): Image.asset('assets/none.png') 

And so, when I removed all alreadyDdl variables from my code, It will make an http request every 15 miliseconds. I want to stop the http request once the image is really downloaded...

CodePudding user response:

use this package to load image url it will avoid unnecessary requests

https://pub.dev/packages/cached_network_image

and check your whole code for unnecessary or repetitive state refresh

CodePudding user response:

You can use a future builder to create widgets based on the latest snapshot of interaction with a Future. You can use it in combination with cached_network_image package as suggested above.

Here's a sample code that demonstrates so:

import "package:flutter/material.dart";
//Your other imports...

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _MyApp();
  }
}

class _MyApp extends State<MyApp> {
  var db;

  @override
  initState() {
    db = Localstore.instance;
  }

  getLogoUrl(context) async {
    final data = db.collection('inputs').doc("1").get();
    var database = (await data)["content"].toString();
    var form = new DGForm("project/getwebsitelogo", {"database": database});
    var ret = await form.urlGET(context);
    ResponseObject responseObject =
        ResponseObject.fromJson(json.decode(ret.body));
    print("hola");
    var hola = (responseObject.datas[0][0].toString());
    bandeauDuClient = hola;
    print(hola);
    return hola;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder(
        future: getLogoUrl(context),
        builder: (ctx, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            // if we got our data
            if (snapshot.hasData) {
              return CachedNetworkImage(
        imageUrl: snapshot.data,
        progressIndicatorBuilder: (context, url, downloadProgress) => 
                CircularProgressIndicator(value: downloadProgress.progress),
        errorWidget: (context, url, error) => Icon(Icons.error),
     );
            } else {
              // If we probably got an error check snapshot.hasError
              return Center(
                child: Text(
                  '${snapshot.error} occurred',
                  style: TextStyle(fontSize: 18),
                ),
              );
            }
          } else {
            return const CircularProgressIndicator();
          }
        },
      ),
    );
  }
}

Note: Never make networking calls in build method because build method is usually called 60 times per second to render. Make network calls in initState or in widgets like FutureBuilder which handle these things for you.

  • Related