Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
boozy-ph opened this issue Oct 7, 2019 · 9 comments

Comments

@boozy-ph
Copy link

boozy-ph commented Oct 7, 2019

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
@escamoteur
Copy link
Collaborator

escamoteur commented Oct 7, 2019

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

@boozy-ph
Copy link
Author

boozy-ph commented Oct 7, 2019

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

@boozy-ph
Copy link
Author

boozy-ph commented Oct 7, 2019

@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

@escamoteur
Copy link
Collaborator

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,
                      ));
                })

@boozy-ph
Copy link
Author

boozy-ph commented Oct 7, 2019

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());
}

@escamoteur
Copy link
Collaborator

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

@boozy-ph
Copy link
Author

boozy-ph commented Oct 7, 2019

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

@escamoteur
Copy link
Collaborator

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

@freeman29
Copy link

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.

@boozy-ph boozy-ph closed this as completed Oct 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants