2

I am new to Flutter and finding it difficult to update _users with a map I get from API. I get build errors even though no actual errors are shown in VSCode.

Here is my code.

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:http/http.dart' as http;

class Users with ChangeNotifier {
  final String id;
  final String firstName;
  final String lastName;
  final String emailAddress;
  final String phoneNumber;
  final String classId;
  final String roleId;
  final String dateCreated;
  final String uid;
  bool isActive;
  final String profilePhoto;

  Users({
    required this.id,
    required this.firstName,
    required this.lastName,
    required this.emailAddress,
    required this.phoneNumber,
    required this.classId,
    required this.roleId,
    required this.dateCreated,
    required this.uid,
    required this.isActive,
    required this.profilePhoto,
  });

  Map<String, Users> _users = {};

  Map<String, Users> get users {
    return {..._users};
  }

  Future<void> fetchUser() async {
    try {
      final String idToken =
          await FirebaseAuth.instance.currentUser!.getIdToken();

      final reauthUrl = Uri.parse(
          'https://example-backend.azurewebsites.net/api/v1/User/reauth');

      final reauthResponse = await http.post(reauthUrl,
          headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json'
          },
          body: json.encode({"token": idToken}));

      final returnedTokenData =
          json.decode(reauthResponse.body) as Map<String, dynamic>;

      final serverToken = returnedTokenData['token'];

      final url =
          Uri.parse('https://example-backend.azurewebsites.net/api/v1/User');

      final response = await http.get(
        url,
        headers: {'Authorization': 'Bearer $serverToken'},
      );

      final responseData = json.decode(response.body) as Map<String, dynamic>;
      Map<String, dynamic> userData = {};
      userData.update(id, (value) {
        return Users(
          id: responseData['id'],
          firstName: responseData['firstName'],
          lastName: responseData['lastName'],
          emailAddress: responseData['emailAddress'],
          phoneNumber: responseData['phoneNumber'],
          classId: responseData['classId'],
          roleId: responseData['roleId'],
          dateCreated: responseData['dateCreated'],
          uid: responseData['uid'],
          isActive: responseData['isActive'],
          profilePhoto: responseData['profilePhoto'],
        );
      });
      print(userData);

      notifyListeners();
    } catch (error) {
      rethrow;
    }
  }
}
11
  • what build errors are you getting? try to reload vscode, this will cause dart analyzer to restart. also check if you're not filtering errors shown in vscode. Commented Jun 3, 2022 at 19:43
  • Not sure if that causing any problem, but the use of userData.update seems really weird to me. Why not just do userData[id] = Users(...) ? Commented Jun 3, 2022 at 19:47
  • Also, in advance, you should notice that responseData['id'], for instance, is not a String, it is a String? (nullable). If any of these fields are null, then your app should throw an Exception while reading responseData and cause your app to crash, because id cannot be null in your Users class Commented Jun 3, 2022 at 19:49
  • 1
    @EricOmine. Thanks for your reply. I actually got rid of the build error by adding null check on the variables in the Users class and replacing 'required' with '@required' in the constructor. The build error was caused by the main.dart file needing arguments for those parameters as the Class is being called on the routes table. The actual problem now is that the code does not work for updating the map. Commented Jun 3, 2022 at 19:54
  • 1
    Method update means updating a specific value in the map that can be read by key that you pass in the first argument of the update method. But your userData is empty and cannot be updated because it doesn't have any values. Commented Jun 3, 2022 at 20:11

1 Answer 1

1

One way to fix the issue is to not use maps and assign the values from the API directly to the variables in your class. The variables should not be final to be able to reassign values to them.

final responseData = json.decode(response.body) as Map<String, dynamic>;
id = responseData['id'];
      firstName = responseData['firstName'];
      lastName = responseData['lastName'];
      emailAddress = responseData['emailAddress'];
      phoneNumber = responseData['phoneNumber'];
      classId = responseData['classId'];
      roleId = responseData['roleId'];
      dateCreated = responseData['dateCreated'];
      uid = responseData['uid'];
      isActive = responseData['isActive'];
      profilePhoto = responseData['profilePhoto'];
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.