skip to Main Content

I’m having trouble accessing the state in bloc consumer

This is repository implementation class for managing errors

class UserRepositoryImplementation implements UserRepository {
  const UserRepositoryImplementation(this._remoteDataSource);

  final UserRemoteDatasource _remoteDataSource;

  @override
  ResultFuture<List<UserListModel>> fetchAllUsers() async {

    try {
      final result = await _remoteDataSource.fetchAllUsers();
    
      return Right(result);
    } on ServerException catch (e) {
      return Left(ServerFailure(message: e.message, statusCode: e.statusCode));
    }
  }
}

This is a class for managing remote data requests

abstract class UserRemoteDatasource {
  const UserRemoteDatasource();

  Future<List<UserListModel>> fetchAllUsers();
}

const baseUrl = 'http://192.168.31.163:8000/api/';

class UserRemoteDatasourceImplementation implements UserRemoteDatasource {
  const UserRemoteDatasourceImplementation(
    this.client,
  );

  final http.Client client;

  Uri getUrl({
    required String url,
    Map<String, String>? extraParameters,
  }) {
    final queryParameters = <String, String>{'key': ''};
    if (extraParameters != null) {
      queryParameters.addAll(extraParameters);
    }

    return Uri.parse('$baseUrl/$url').replace(
      queryParameters: queryParameters,
    );
  }

  _header(token) => {
        'Content-type': 'application/json',
        'Charset': 'utf-8',
        'Authorization': 'Bearer $token',
      };

  @override
  Future<List<UserListModel>> fetchAllUsers() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String token = prefs.getString('token').toString();
    try {
      final response = await client.post(
          Uri.parse('http://192.168.31.163:8000/api/me'),
          headers: _header(token));

      final data = jsonDecode(response.body);

      if (data == null) {
        throw const ServerException(
          message: 'Please try again later',
          statusCode: 'Unknown Error',
        );
      }

      final List<dynamic> usersList = data["users"];
      print(usersList
          .map((json) => UserListModel.fromJson(json).toMap())
          .toList());
      final  userList =
          usersList.map((json) => UserListModel.fromJson(json)).toList();
    
      return userList;
    } on ServerException {
      rethrow;
    } catch (e, s) {
      debugPrintStack(stackTrace: s);
      throw ServerException(
        message: e.toString(),
        statusCode: '505',
      );
    }
  }
}

And this is a widget where I’m trying to get users from state and show them in widget as list of items

class UserListScreen extends StatelessWidget {
  const UserListScreen({super.key});
  static const routeName = '/users-list';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: BlocConsumer<UserBlocBloc, UserBlocState>(
          listener: (_, state) {},
          builder: (context, state) {
            print(state);
            return ListView.builder(
              itemCount: state.users.length,
              itemBuilder: (context, index) {
                final users = state.users[index];
               
                ListTile(
                  title: Text('${user.first_name}'),
                  textColor: Colors.white70,
                );
              },
            );
          }),
    );
  }
}

And this is Bloc class for users

class UserBlocBloc extends Bloc<UserBlocEvent, UserBlocState> {
  UserBlocBloc({
    required FetchAllUsers fetchAllUsers,
  })  : _fetchAllUsers = fetchAllUsers,
        super(const UserBlocState()) {
    on<UserBlocEvent>((event, emit) {
      // TODO: implement event handler
    });
    on<FetchAllUsersEvent>(_fetchAllUsersHandler);
  }

  final FetchAllUsers _fetchAllUsers;

  Future<void> _fetchAllUsersHandler(
    FetchAllUsersEvent event,
    Emitter<UserBlocState> emit,
  ) async {
    final result = await _fetchAllUsers();
    print(result);
    result.fold(
      (failure) => emit(state.copyWith(status: UserBlocStatus.error)),
      (users) => emit(
        state.copyWith(
          status: UserBlocStatus.success,
          users: users,
        ),
      ),
    );
  }
}

This is the response from _fetchAllUsers()

[{id: 492d83be-e6b1-4b25-8845-87fc8f080756, username: admin, name: Dusko, last_name: Dusko, token: null}, {id: 9a5e7975-0920-4744-a651-b56720189586, username: vendor, name: sdfsdfs, last_name: sdfdsfsdf, token: null}, {id: 9a5fc3e9-1ae7-4257-8be0-d459237c92c6, username: employee, name: employee, last_name: employee, token: null}]

And this is what I get when printing state in widget

UserBlocState(UserBlocStatus.success, [UserListModel(492d83be-e6b1-4b25-8845-87fc8f080756, admin, Dusko, Dusko, null), UserListModel(9a5e7975-0920-4744-a651-b56720189586, vendor, sdfsdfs, sdfdsfsdf, null), UserListModel(9a5fc3e9-1ae7-4257-8be0-d459237c92c6, employee, employee, employee, null)])

I’m not sure what am I doing wrong. When I print state.users length is 3. But besides that I cannot access any item inside of it.
Hopefully there’s a good soul to guide me through this mess…

2

Answers


  1. Chosen as BEST ANSWER

    That’s not the case. I’ve figured that out last night. Just had to loop through list. Like this ...users.map((item) => Text(item.first_name)).toList().


  2. The only problem seems to be the missing return inside the ListView.builder callback:

    return ListView.builder(
      itemCount: state.users.length,
      itemBuilder: (context, index) {
        final users = state.users[index];
                   
        return ListTile(
          title: Text('${user.first_name}'),
          textColor: Colors.white70,
        );
      },
    );
    

    Can you provide UserListModel too? Looks like you try to access first_name but the json returned by _fetchAllUsers doesn’t seem to have it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search