jonataslaw / getx

Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.
MIT License
10.41k stars 1.63k forks source link

getx GetConnect onInit not work #2540

Open giantss opened 2 years ago

giantss commented 2 years ago

getx GetConnect onInit not working causing this error. Unhandled Exception: Invalid argument(s): No host specified in URI albums/1

Here is a simple example https://github.com/giantss/flutterGetxTest/tree/main/testapp

example:

home_binding.dart

import 'package:get/get.dart';
import 'package:testapp/app/modules/home/providers/home_provider.dart';

import '../controllers/home_controller.dart';

class HomeBinding extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut<HomeController>(
      () => HomeController(),
    );
    Get.lazyPut<HomeProvider>(
          () => HomeProvider(),
    );
  }
}

home_provider.dart

import 'package:get/get.dart';
import '../home_model.dart';

class HomeProvider extends GetConnect {
  @override
  void onInit() {    // no call
    httpClient.defaultDecoder = (map) {
      if (map is Map<String, dynamic>) return Home.fromJson(map);
      if (map is List) return map.map((item) => Home.fromJson(item)).toList();
    };
    httpClient.baseUrl = 'https://jsonplaceholder.typicode.com/';   
  }

  Future<Home?> getHome(int id) async {
    final response = await get('albums/$id');  // error is thrown here
    return response.body;
  }

  Future<Response<Home>> postHome(Home home) async => await post('home', home);
  Future<Response> deleteHome(int id) async => await delete('home/$id');
}

pubspec.yaml

name: testapp
version: 1.0.0+1
publish_to: none
description: A new Flutter project.
environment: 
  sdk: '>=2.17.6 <3.0.0'

dependencies: 
  cupertino_icons: ^1.0.2
  get: 4.6.5
  flutter: 
    sdk: flutter

dev_dependencies: 
  flutter_lints: 2.0.1
  flutter_test: 
    sdk: flutter

flutter: 
  uses-material-design: true
giantss commented 2 years ago

@jonataslaw Can you help take a look? This problem has been bothering me for a while.

pratamatama commented 2 years ago

@giantss You have to use Get.put instead of Get.lazyPut for the provider.

giantss commented 2 years ago

@giantss You have to use Get.put instead of Get.lazyPut for the provider.

@pratamatama The demo I provided is replaced with the following code and it still doesn't work.

class HomeBinding extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut<HomeController>(
      () => HomeController(),
    );
    Get.put(HomeProvider);
    // Get.lazyPut<HomeProvider>(
    //       () => HomeProvider(),
    // );
  }
}
pratamatama commented 2 years ago

@giantss put it above your lazyput, that should work.

also, you might want to include the parenthesis on the HomeProvider so it doesn't treat it as a Type instead of an instance.

like so


Get.put(HomeProvider());

Get.lazyPut<HomeController>(
    () => HomeController(),
);
giantss commented 2 years ago

@giantss put it above your lazyput, that should work.

also, you might want to include the parenthesis on the HomeProvider so it doesn't treat it as a Type instead of an instance.

like so

Get.put(HomeProvider());

Get.lazyPut<HomeController>(
    () => HomeController(),
);

@jonataslaw Tried it all, still doesn't work. I have a demo example above, can you clone it and help? thank you very much。

image image
kauemurakami commented 2 years ago

I can initialize getconnect's onInit in two ways. extending GetxService and using theinit() implementation, injecting with

await Get.putAsync(() => MyApi().init()); 

and also with GetxService's onInit injecting

Get.put(MyApi())

in this way, the problem at the moment is that even initializing and managing to retrieve the assignments I make in httpClient such as baseUrl being equal to the value I entered in the previous line, and using httClient .<method> or directly get methods like post()or get() it doesn't recognize this variable outside of inits. Hope this helps, although it's not the complete answer. And I'm following

giantss commented 2 years ago

@kauemurakami Thanks a lot for your answer. This is just a very simple demo, and I didn't even write any logic. In theory, this kind of problem should not occur. Is this an official bug? @jonataslaw

GordonHuangYong commented 1 year ago

big bug

levisaturnino commented 1 year ago

Find this website explained as DI functionality, it has some auxiliary parameters that can help the put not die: the-flutter-getx-ecosystem-dependency-injection-

inyong1 commented 1 year ago

I use this code and worked well image

pratamatama commented 1 year ago

@giantss put it above your lazyput, that should work. also, you might want to include the parenthesis on the HomeProvider so it doesn't treat it as a Type instead of an instance. like so

Get.put(HomeProvider());

Get.lazyPut<HomeController>(
    () => HomeController(),
);

@jonataslaw Tried it all, still doesn't work. I have a demo example above, can you clone it and help? thank you very much。

image image

I think I see the problem. You are putting a GetConnect provider into the binding, but then directly instantiating it inside the controller. You can't do that.

Instead of doing var provider = HomeProvider(), try to use final provider = Get.find<HomeProvider>(). It will use the instance of HomeProvider that was previously being injected from the binding.

OR... If you prefer, refactor your code to be more like this.

home_bindings.dart

class HomeBinding extends Bindings {
  @override
  void dependencies() {
    Get.lazyPut(
      () => HomeController(
        provider: Get.put(HomeProvider()), // HERE
      )
    );
  }
}

home_controller.dart

class HomeController extends GetxController {
  HomeController({ required HomeProvider provider }) : _provider = provider; // HERE
  final HomeProvider _provider;

  final homeData = Home().obs;

  @override
  void onInit() {
    fetchHomeData();
    super.onInit();
  }

  void fetchHomeData() {
    homeData.value = _provider.getHome(1) as Home;
  }
}

@giantss

kauemurakami commented 3 months ago

I was able to use it this way #894, I hope I can still help, in this case the problem was set baseUrl, but also apply same modifiers.