fluttercommunity/rx_command

type 'LocationModel' is not a subtype of type 'CommandResult<LocationModel>'

boozy-ph opened this issue · 9 comments

What should be the correct snapshot type using streambuilder?
The codes are the following:

StreamBuilder

StreamBuilder(
                initialData:
                    sl.get<LocationsManager>().selectLocationCommand.lastResult,
                stream:
                    sl.get<LocationsManager>().selectLocationCommand.results,
                builder: (context, snapshot) {
                  CommandResult<LocationModel> result = snapshot.data;
                  return Text(result.data.city,
                      style: TextStyle(
                        fontSize: 14.0,
                        color: Colors.orange,
                        decoration: TextDecoration.underline,
                      ));
                })

LocationsManager

class LocationsManager {
  RxCommand<String, List<LocationModel>> updateLocationsCommand;
  RxCommand<LocationModel, LocationModel> selectLocationCommand;

  LocationsManager() {
    updateLocationsCommand = RxCommand.createAsync<String, List<LocationModel>>(
        (String query) => sl.get<LocationsService>().getLocations(query));

    selectLocationCommand = RxCommand.createSync<LocationModel, LocationModel>(
        (LocationModel location) {
      return location;
    }, emitInitialCommandResult: true);
  }
}

If I'm gonna remove CommandResult<LocationModel> result = snapshot.data; it will throw an Error:

Class 'CommandResult<LocationModel>' has no instance getter 'city'.
Receiver: Instance of 'CommandResult<LocationModel>'
Tried calling: city

you have to use result.data.data
The first data comes from the snapshot, the second from the CommandResult

@escamoteur, you mean with my existing code and without CommandResult<LocationModel> result = snapshot.data;, I should use snapshot.data.data.city?

@escamoteur your right the error type 'LocationModel' is not a subtype of type 'CommandResult<LocationModel>' was resolve, but when I change route another error occur:

Class 'LocationModel' has no instance getter 'data'.
Receiver: Instance of 'LocationModel'
Tried calling: data

It depends :-)

If you need inside your StreamBuilder data, busy and error then you have to use CommandResult<LocationModel> as your generic Type so

Btw yu can omit the getof GetIt because its a callable class

StreamBuilder<CommandResult<LocationModel>>(
//    With CommandResult this doesn't work because lastResult would just be a LocationModel, not aCommandResult<LocationModel>
//            initialData:
//                    sl<LocationsManager>().selectLocationCommand.lastResult,
//    So either leave empty or use 
            initialData:
                    CommandResult<LocationModel>( sl<LocationsManager>().selectLocationCommand.lastResult, null, false) ,
                stream:
                    sl<LocationsManager>().selectLocationCommand.results,
                builder: (context, snapshot) {
                  CommandResult<LocationModel> result = snapshot.data.data;
                  return Text(result.data.city,
                      style: TextStyle(
                        fontSize: 14.0,
                        color: Colors.orange,
                        decoration: TextDecoration.underline,
                      ));
                })

Always tell StreamBuilder which Type you expect.

If you are only interested in the data, because you might listen to the thrownExceptions elsewhere

You use the Command directly without the .resultlike

StreamBuilder<LocationModel>(
                initialData:
                    sl<LocationsManager>().selectLocationCommand.lastResult,
                stream:
                    sl<LocationsManager>().selectLocationCommand.results,
                builder: (context, snapshot) {
                  LocationModel result = snapshot.data;
                  return Text(result.data.city,
                      style: TextStyle(
                        fontSize: 14.0,
                        color: Colors.orange,
                        decoration: TextDecoration.underline,
                      ));
                })

Thanks @escamoteur ! Here's the final StreamBuilder that works for me:

StreamBuilder<CommandResult<LocationModel>>(
                initialData: CommandResult<LocationModel>(
                    sl.get<LocationsManager>().selectLocationCommand.lastResult,
                    null,
                    false),
                stream:
                    sl.get<LocationsManager>().selectLocationCommand.results,
                builder: (context, snapshot) {
                  LocationModel result = snapshot.data.data;
                  return Text(
                    result.city,
                    style: TextStyle(
                      fontSize: 14.0,
                      color: Colors.orange,
                      decoration: TextDecoration.underline,
                    ),
                  );
                })

omitting the get on sl class throws runtime error maybe because of how I instantiate sl class?
here's my code on it:

GetIt sl = GetIt.instance;

final httpLink = ...

final GraphQLClient client = GraphQLClient(
  cache: InMemoryCache(),
  link: httpLink,
);

void setUpServiceLocator() {
  // Services
  sl.registerSingleton<LocationsService>(LocationsService(http.Client()));
  sl.registerSingleton<CollectionService>(CollectionService(http.Client()));

  // Managers
  sl.registerSingleton<LocationsManager>(LocationsManager());
  sl.registerSingleton<CollectionManager>(CollectionManager());
  sl.registerSingleton<RouteManager>(RouteManager());
}

Um this should work, what exxor did you get? Did you possible delete the () ? it shout be sl<YourType>()

Errors are:

The getter '<' isn't defined for the class 'GetIt'.
Try importing the library that defines '<', correcting the name to the name of an existing getter, or defining a getter or field named '<'.

and Unexpected text '.'

I'm using get_it: ^3.0.1

ahh could you just show me the line looks where the error is? And the one below?

ahh could you just show me the line looks where the error is? And the one below?

Sorry my bad again I did this sl.<LocationsManager>().selectLocationCommand.results that supposed to be sl<LocationsManager>().selectLocationCommand.results without the dot after sl.

Thanks again @escamoteur and for all your great packages, you are awesome mate.