Search code examples
formsflutterdartflutter-providertextformfield

Modifying User Data with Class and Provider (Without FireBase)


I'm currently making UserPage and UserModifyPage. And now I have UserClass that just stores User Information, and User-Provider to modify UserData.

But when I click the MODIFY Page, it just shows

The getter 'id' was called on null.

enter image description here

So this picture is 'Settings.dart' Page display UserName and UserEmail

enter image description here

And the other one is the ModifyUser.dart page that modifies UserData.

Here are my codes below.

1. User.dart (Model)

import 'package:flutter/material.dart';


class User{
  String id;
  String userName;
  String email;
  // final String photoURL;
  // List<String> photoURL;
  String photoURL;
  String userAddress;
  
  User({
    // this.id,
    @required this.id,
    @required this.userName,
    @required this.email,
    @required this.photoURL,
    @required this.userAddress
  });

  factory User.from(User user){
    return User(
      id: user.id ?? '',
      userName: user.userName ?? '',
      email: user.email ?? '',
      // photoURL: user.photoURL ?? [],
      photoURL: user.photoURL ?? '',
      userAddress: user.userAddress ?? '',
    );
  }
}

2. UserProvider.dart

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_app/model/game/Users.dart';


class UserProvider with ChangeNotifier{
  List<User> _userInfoList = [];
  User _userModify;

  List<User> get userInfoList {
    return [..._userInfoList];
  }

  User get userModify{
    return User.from(_userModify);
  }
  setname(User user){
    _userModify.userName = user.userName;
    notifyListeners();
  }

  void createUserInfo(User userModfiy){
    if (userModify != null){
      // User.fro = userModify.id ?? '';
      final User modifyUser = User.from(userModfiy);
      // modifyUser.id = modifyUser.id ?? 'test';
      // modifyUser.email = modifyUser.email ?? '';
      modifyUser.userName = modifyUser.userName ?? '';

    }
  }

  void changeUserInfo(User userModfiy, String userName, String email, String imageURL, String address){
    // userModfiy.userName = userName
    // userModfiy.email = email;
    // userModfiy.photoURL = imageURL;
    // userModfiy.userAddress = address;
    // notifyListeners();
    final int index = _userInfoList.indexWhere((userInfo) => userInfo.id == _userModify.id);
    if(index != 1){
      final User modifyUser = User.from(userModify);
      modifyUser.userName = userName;
      modifyUser.email = email;
      modifyUser.photoURL = imageURL;
      modifyUser.userAddress = address;
    }
    notifyListeners();
  }
}

3. Settings.dart

import 'package:flutter/material.dart';
import 'package:flutter_app/Provider/users.dart';
import 'package:flutter_app/app_screens/app_attributes/SettingsImage.dart';
import 'package:flutter_app/model/game/Users.dart';
import 'package:flutter_app/shared/style.dart';
import 'package:flutter_app/widgets/Commons/details_form.dart';
import 'package:flutter_app/app_screens/SideMenu.dart';
import 'package:provider/provider.dart';


class Setting extends StatefulWidget {
  @override
  _SettingState createState() => _SettingState();
}

class _SettingState extends State<Setting> {
  User userModification;
  final TextEditingController userNameTextController = TextEditingController();
  final TextEditingController userEmailTextController = TextEditingController();
  final TextEditingController userAddressController = TextEditingController();
  final TextEditingController userImageTextController = TextEditingController();
  // @override
  // void initState(){
  //   setState((){
  //     userModification = Provider.of<UserProvider>(context, listen: false).userModify;
  //   });
  //   if(userModification == null){
  //     print("Pass me the Salt Please Man!!!");
  //     // final List<User> userInfoList = Provider.of<UserProvider>(context, listen: false).i
  //   }
  // }
  AppBar _buildAppBarSettings(){
    return AppBar(
      title: Text("SETTINGS"),
      backgroundColor: appBarColor,
      centerTitle: true,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: SideMenu(),
      appBar: _buildAppBarSettings(),
      body: _buildSettingsBody(context),
    );
  }

  Widget _buildSettingsBody(BuildContext context){
    double screenHeight = MediaQuery.of(context).size.height;

    return Container(
      height: screenHeight,
      color: backgroundColor,
      child: Stack(
        overflow: Overflow.visible,
        children: [
          Padding(
            padding: EdgeInsets.symmetric(vertical: 20, horizontal: defaultPadding),
            child: SingleChildScrollView(
              child: Column(
                children: [
                  _buildProfileImage(),
                  SizedBox(height: defaultPadding * 4),
                  _buildProfileInfo(),
                ],
              ),
            )
          ),
          _buildEditButton(context)
        ], 
      )
    );
  }

  Widget _buildProfileImage(){
    return Column(
      children: <Widget>[
        Center(child: ProfileImageButton(),),
        SizedBox(height: defaultPadding),
        Center(
          child: Text(_getUserName(), style: TextStyle(fontSize: 24)),
        ),
      ]
    );
  }

  Widget _buildProfileInfo(){
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        DetailsForm(
          contentsTitle: "Local ID",
          contentsInfo: "8VxqWO9pRBTvpLGxFXquloo97X13",
          marginBottom: defaultPadding * 2,
        ),
        DetailsForm(
          contentsTitle: "Email",
          contentsInfo: _getEmail(),
          marginBottom: defaultPadding * 2,
        ),
        DetailsForm(
          contentsTitle: "Address",
          contentsInfo: _getAddress(),
          marginBottom: defaultPadding * 2,
        ),
      ]
    );
  }

  Widget _buildEditButton(BuildContext context){
    return Positioned(
      bottom: 0,
      left: 0,
      right: 0,
      
      child: FlatButton(
        shape: ContinuousRectangleBorder(side: BorderSide(color: lineColor)),
        color: Colors.black87,
        child: Padding(
          padding: EdgeInsets.all(defaultPadding / 2),
          child: Text("EDIT", style: settingsMainFont),
        ),
        onPressed: () {
          Navigator.pushNamed(context, "/modify");
        },
      ),
    );
  }

  String _getUserName(){
    return userNameTextController.text == null ||
      userNameTextController.text.trim().isEmpty ? 'YourName'
      : userNameTextController.text;
  }

  String _getEmail(){
    return userEmailTextController.text == null ||
      userEmailTextController.text.trim().isEmpty? 'text@gmail.com'
      : userEmailTextController.text;
  }

  String _getImageLink(){
    return userImageTextController.text == null ||
      userImageTextController.text.trim().isEmpty? 'http://url.com'
      : userImageTextController.text;
  }

  String _getAddress(){
    return userAddressController.text == null ||
      userAddressController.text.trim().isEmpty? 'YourLocation'
      : userAddressController.text;
  }
}

4. ModifyProfile.dart

import 'package:flutter/material.dart';
import 'package:flutter_app/Provider/users.dart';
import 'package:flutter_app/app_screens/SideMenu.dart';
import 'package:flutter_app/model/game/Users.dart';
import 'package:flutter_app/shared/style.dart';
import 'package:flutter_app/widgets/Commons/details_form.dart';
import 'package:flutter_app/widgets/DetailsPage/label.dart';
import 'package:provider/provider.dart';

import 'package:flutter_app/model/game/Users.dart';


class ModifyProfile extends StatefulWidget {
  @override
  _ModifyProfileState createState() => _ModifyProfileState();
}

class _ModifyProfileState extends State<ModifyProfile> {
  final _formModifyKey = GlobalKey<FormState>();
  final TextEditingController userNameTextController = TextEditingController();
  
  User user;
  String _userName = 'UserName';
  String _email = 'dddd@gmail.com';
  String _imageURL = 'https://www.naver.com';
  String _address = 'SK Seongsu V1 CENTER I, Seongsu-dong 2-ga, Seongdong-du, Seoul, S.Korea';
  bool _isInit = false;

  final Map<String, dynamic> _formUserData = {
    'username': '',
    'email': '',
    'imageURL': '',
    'Address': '',
    // ''
  };


  Widget _buildModifyAppBar(){
    return AppBar(
      backgroundColor: appBarColor,
      title: Text("MODIFY PROFILE"),
      centerTitle: true,
    );
  }

  Widget _buildModifyBody(){
    double screenHeight = MediaQuery.of(context).size.height;

    return Container(
      height: screenHeight,
      color: backgroundColor,
      child: Stack(
        overflow: Overflow.visible,
        children: [
          Padding(
            // padding: EdgeInsets.symmetric(vertical: defaultPadding, horizontal: defaultPadding),
            padding: EdgeInsets.all(defaultPadding * 2),
            child: SingleChildScrollView(
              child: Consumer<UserProvider>(
                builder: (ctx, user, _){
                  final List<User> userList = user.userInfoList;
                  if(user != null && !_isInit){
                    print("Initialize..");
                    _formUserData['username'] = userList;
                    _formUserData['email'] = userList;
                    _formUserData['imageURL'] = userList;
                    _formUserData['Address'] = userList;
                  }
                  return Form(
                    key: _formModifyKey,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Label(label: "UserName"),
                        // _buildModifyText(),
                        _buildUserNameModify(),
                        // Label(label: "Email"),
                        // _buildModifyText(),
                        // _buildUserEmailModify(),
                        // Label(label: "Image URL"),
                        // _buildModifyText(),
                        // // _buildUserImageURLModify(),
                        // Label(label: "Address"),
                        // _buildModifyText(),
                        // _buildUserAddressModify(),
                      ],
                    )
                  );
                }
              )
              
            )
          ),
          _buildModifyForm(),
        ],
      )
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _buildModifyAppBar(),
      body: _buildModifyBody(),
    );
  }

  Widget _buildUserNameModify(){
    return Column(
      children: <Widget>[
         TextFormField(
          // controller: SideMenu().userNameTextController,
          validator: (value){
            if(value.isEmpty) {return 'Please enter some text';}
            return null;
          },
          onChanged: (value){
            _formModifyKey.currentState.validate();
          },
          onSaved: (value){
            print("User Edition!!!!!");
            setState((){
              _formUserData['username'] = value;
              // _userName = value;
              print(value);
            });
            print(value);
          },
        ),
        SizedBox(height: defaultPadding * 2),
      ],
    );
  }

  Widget _buildModifyForm(){
    return Positioned(
      bottom: 0,
      left: 0,
      right: 0,
      
      child: FlatButton(
        shape: ContinuousRectangleBorder(side: BorderSide(color: lineColor)),
        color: Colors.black87,
        child: Padding(
          padding: EdgeInsets.all(defaultPadding / 2),
          child: Text("MODIFY", style: settingsMainFont),
        ),
        onPressed: () => _submitForm(context)
      ),
    );
  }



  void _submitForm(BuildContext context){
    if(!_formModifyKey.currentState.validate()) return;
    _formModifyKey.currentState.save();
    
    Provider.of<UserProvider>(context).createUserInfo(user);
    print(user.userName);
    // print(user.email);
    // Provider.of<UserProvider>(context).changeUserInfo(user, _userName, _email, _imageURL, _address);
    // print(_userName);
    // print(_email);
    // print(_imageURL);
    // print(_address);
    Navigator.of(context).pop();
  }
}

Solution

  • I think the problem is in your changeUserInfo. You are not using the parameter, userModify. To use it, you should change the relevant part with the following:

    
     void changeUserInfo(User userModify, String userName, String email, String imageURL, String address){
        // userModfiy.userName = userName
        // userModfiy.email = email;
        // userModfiy.photoURL = imageURL;
        // userModfiy.userAddress = address;
        // notifyListeners();
        // In here!
        final int index = _userInfoList.indexWhere((ui) => ui.id == userModify.id);
        if(index != 1){
          final User modifyUser = User.from(userModify);
          modifyUser.userName = userName;
          modifyUser.email = email;
          modifyUser.photoURL = imageURL;
          modifyUser.userAddress = address;
        }
        notifyListeners();
      }