Ansh
Ansh

Reputation: 2396

How do I use flutter bloc pattern to load list of data with paging?

I am using flutter_bloc in my application and referring to this sample. Now when I am running my application it gives me an error saying:

flutter: type 'MovieUninitialized' is not a subtype of type 'MovieLoaded' in type cast

My bloc contains three files: movie_state, movie_event, and movie_bloc

movie_state.dart

import 'package:equatable/equatable.dart';
import 'package:movie_project/models/movie.dart';

abstract class MovieState extends Equatable {
  MovieState([List props = const []]) : super(props);
}

class MovieUninitialized extends MovieState {
  @override
  String toString() => 'MovieUninitialized';
}

class MovieError extends MovieState {
  @override
  String toString() => 'MovieError';
}

class MovieLoaded extends MovieState {
  final List<Movie> movies;
  final bool hasReachedMax;
  // Keeps track of the page to fetch the latest movies from the api
  final latestMoviesPage;

  MovieLoaded({
    this.movies,
    this.hasReachedMax,
    this.latestMoviesPage,
  }) : super([movies, hasReachedMax, latestMoviesPage]);

  MovieLoaded copyWith({
    List<Movie> movies,
    bool hasReachedMax,
    int latestMoviesPage,
  }) {
    return MovieLoaded(
      movies: movies ?? this.movies,
      hasReachedMax: hasReachedMax ?? this.hasReachedMax,
      latestMoviesPage: this.latestMoviesPage,
    );
  }

  @override
  String toString() =>
      'PostLoaded { posts: ${movies.length}, hasReachedMax: $hasReachedMax }';
}

movie_event.dart

import 'package:equatable/equatable.dart';

abstract class MovieEvent extends Equatable {}

class Fetch extends MovieEvent {
  @override
  String toString() => 'Fetch';
}

movie_bloc.dart

class MovieBloc extends Bloc<MovieEvent, MovieState> {
  final MovieRepository movieRepository;

  MovieBloc({@required this.movieRepository});

  @override
  Stream<MovieState> transform(
    Stream<MovieEvent> events,
    Stream<MovieState> Function(MovieEvent event) next,
  ) {
    return super.transform(
      (events as Observable<MovieEvent>).debounceTime(
        Duration(milliseconds: 500),
      ),
      next,
    );
  }

  @override
  MovieState get initialState => MovieUninitialized();

  @override
  Stream<MovieState> mapEventToState(MovieEvent event) async* {
    if (event is Fetch && !_hasReachedMax(currentState)) {
      try {
        if (currentState is MovieUninitialized) {
          final movies = await movieRepository.fetchMovies(1);
          yield MovieLoaded(
            movies: movies,
            hasReachedMax: false,
            latestMoviesPage:
                (currentState as MovieLoaded).latestMoviesPage + 1,
          );
          return;
        }
        if (currentState is MovieLoaded) {
          final movies = await movieRepository
              .fetchMovies((currentState as MovieLoaded).latestMoviesPage);
          yield movies.isEmpty
              ? (currentState as MovieLoaded).copyWith(hasReachedMax: true)
              : MovieLoaded(
                  movies: (currentState as MovieLoaded).movies + movies,
                  hasReachedMax: false,
                  latestMoviesPage:
                      (currentState as MovieLoaded).latestMoviesPage + 1,
                );
        }
      } catch (_) {
        print(_);
        yield MovieError();
      }
    }
  }

  bool _hasReachedMax(MovieState state) =>
      state is MovieLoaded && state.hasReachedMax;
}

I need to increment the latestMoviesPage until it reaches the max limit. If I remove latestMoviesPage from my bloc code issue gets resolves but I really need it to load more pages.

Upvotes: 1

Views: 3145

Answers (1)

Ansh
Ansh

Reputation: 2396

Instead of

latestMoviesPage: (currentState as MovieLoaded).latestMoviesPage + 1,

I need to write:

latestMoviesPage: 2,

Upvotes: 1

Related Questions