Search code examples
fluttersql-updatesqflite

how to update table in sqflite with flutter


when I try to update a table with id nothing won't happen. I got no error and I have no idea why this happens. at first, I try to get all data from fields, and then if all fields have value then make the User object and pass into the method for the update table. I got id from the previous screen and other data from fields. as I check I have all data inside the validate method in CompleteUserInformationScreen and I think error occur somewhere when I try to call update method with sqflite.

this is my method for the update table:

 Future<User> update(User user) async {
    var dbClient = await db;
    // return await dbClient.update(USER_TABLE, user.toMap(),
    //     where: '$NATIONAL_ID = ?', whereArgs: [user.nationalId]);
    var res = await dbClient.rawQuery(
        'UPDATE Customer SET $NAME = ${user.name}, $FAMILY = ${user.family}, $BIRTHDAY = ${user.birthday}, $MOBILE = ${user.mobile}, $NATIONAL_ID = ${user.nationalId} WHERE id = ${user.id}');

    if (res.length > 0) {
      return new User.fromMap(res.first);
    }
    return null;
  }

and this is my screen :

import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
import 'package:atlas_gen_demo/Animation/FadeAnimation.dart';
import 'package:flutter/services.dart';
import '../models/user.dart';
import 'package:flushbar/flushbar.dart';
import 'package:atlas_gen_demo/data/storage/db_helper.dart';
import 'package:atlas_gen_demo/screens/users_list_screen.dart';

class CompleteUserInformationScreen extends StatelessWidget {
  static const routeName = '/complete-user-information';

  final nameController = TextEditingController();
  final familyController = TextEditingController();
  final nationalIdController = TextEditingController();
  final mobileController = TextEditingController();

  var id;
  var birthday;


  validate(BuildContext ctx) async {
    if (nameController.text != "" &&
        familyController.text != "" &&
        nationalIdController.text != "" &&
        mobileController.text != "") {
      final dbHelper = DBHelper();
      print("useriddd: $id   birthdayyyy: ${birthday.toString()}");
      User user = await dbHelper.update(User(
          id,
          nameController.text,
          familyController.text,
          null,
          null,
          birthday,
          mobileController.text,
          nationalIdController.text));
      if (user.username != "") {
        navigateToUsersList(ctx);
      }
    } else {
  //     showFlushBar(ctx, "fault", "fill all fields");
    }
  }

  void navigateToUsersList(BuildContext ctx) {
    Navigator.of(ctx).pushNamed(
      UsersListScreen.routeName,
    );
  }

  void showFlushBar(BuildContext context, String title, String text) {
    Flushbar(
      padding: EdgeInsets.all(10),
      borderRadius: 8,
      backgroundGradient: LinearGradient(
        colors: [Colors.purple.shade800, Colors.purpleAccent.shade700],
        stops: [0.6, 1],
      ),
      boxShadows: [
        BoxShadow(
          color: Colors.black,
          offset: Offset(3, 3),
          blurRadius: 3,
        )
      ],
      dismissDirection: FlushbarDismissDirection.HORIZONTAL,
      forwardAnimationCurve: Curves.fastLinearToSlowEaseIn,
      titleText: Text(
        title,
        style: TextStyle(fontFamily: 'mainBold', color: Colors.white),
      ),
      messageText: Text(
        text,
        style: TextStyle(fontFamily: 'mainMedium', color: Colors.white),
      ),
      duration: Duration(seconds: 3),
    ).show(context);
  }

  @override
  Widget build(BuildContext context) {
    final userId = ModalRoute.of(context).settings.arguments;
    return Scaffold(
      backgroundColor: Colors.white,
      body: SingleChildScrollView(
        child: Container(
          child: Column(
            children: <Widget>[
              Container(
                height: 250,
                margin: EdgeInsets.only(top: 50),
                decoration: BoxDecoration(
                  image: DecorationImage(
                    image: AssetImage('assets/images/complete_profile.png'),
                    fit: BoxFit.fill,
                  ),
                ),
              ),
              Positioned(
                child: FadeAnimation(
                    1.8,
                    InkWell(
                      child: Container(
                        margin: EdgeInsets.only(top: 10),
                        child: Center(
                          child: Text(
                            "Complete data",
                            textAlign: TextAlign.center,
                            style: TextStyle(
                              color: Color.fromRGBO(143, 148, 251, 1),
                              fontSize: 20,
                              fontWeight: FontWeight.bold,
                              fontFamily: 'persianBold',
                            ),
                          ),
                        ),
                      ),
                    )),
              ),
              Padding(
                padding: EdgeInsets.all(30.0),
                child: Column(
                  children: <Widget>[
                    Container(
                      padding: EdgeInsets.all(5),
                      decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(10),
                        boxShadow: [
                          BoxShadow(
                              color: Color.fromRGBO(143, 148, 251, .2),
                              blurRadius: 20.0,
                              offset: Offset(0, 10))
                        ],
                      ),
                      child: Column(
                        children: <Widget>[
                          Container(
                            padding: EdgeInsets.all(8.0),
                            decoration: BoxDecoration(
                                border: Border(
                              bottom: BorderSide(color: Colors.grey[100]),
                            )),
                            child: TextFormField(
                              controller: nameController,
                              textDirection: TextDirection.rtl,
                              textAlign: TextAlign.right,
                              decoration: InputDecoration(
                                border: InputBorder.none,
                                hintText: "name",
                                hintStyle: TextStyle(
                                  color: Colors.grey[400],
                                  fontFamily: 'persianMedium',
                                  fontSize: 14,
                                ),
                              ),
                            ),
                          ),
                          Container(
                            padding: EdgeInsets.all(8.0),
                            decoration: BoxDecoration(
                                border: Border(
                              bottom: BorderSide(color: Colors.grey[100]),
                            )),
                            child: TextFormField(
                              controller: familyController,
                              textAlign: TextAlign.right,
                              textDirection: TextDirection.rtl,
                              decoration: InputDecoration(
                                border: InputBorder.none,
                                hintText: "family",
                                hintStyle: TextStyle(
                                  color: Colors.grey[400],
                                  fontFamily: 'persianMedium',
                                  fontSize: 14,
                                ),
                              ),
                            ),
                          ),
                          Container(
                            padding: EdgeInsets.all(8.0),
                            decoration: BoxDecoration(
                                border: Border(
                              bottom: BorderSide(color: Colors.grey[100]),
                            )),
                            child: TextFormField(
                              controller: nationalIdController,
                              textAlign: TextAlign.right,
                              textDirection: TextDirection.rtl,
                              decoration: InputDecoration(
                                border: InputBorder.none,
                                hintText: "national code",
                                hintStyle: TextStyle(
                                  color: Colors.grey[400],
                                  fontFamily: 'persianMedium',
                                  fontSize: 14,
                                ),
                              ),
                            ),
                          ),
                          Container(
                            padding: EdgeInsets.all(8.0),
                            decoration: BoxDecoration(
                                border: Border(
                              bottom: BorderSide(color: Colors.grey[100]),
                            )),
                            child: TextFormField(
                              controller: mobileController,
                              textAlign: TextAlign.right,
                              inputFormatters: [
                                WhitelistingTextInputFormatter.digitsOnly
                              ],
                              textDirection: TextDirection.rtl,
                              decoration: InputDecoration(
                                border: InputBorder.none,
                                hintText: "09123456789",
                                hintStyle: TextStyle(
                                  color: Colors.grey[400],
                                  fontFamily: 'persianMedium',
                                  fontSize: 14,
                                ),
                              ),
                            ),
                          ),
                          FlatButton(
                              onPressed: () {
                                DatePicker.showDatePicker(context,
                                    showTitleActions: true,
                                    minTime: DateTime(1250, 1, 1),
                                    maxTime: DateTime(1450, 12, 31),
                                    onChanged: (date) {
                                  print('change $date');
                                }, onConfirm: (date) {
                                  birthday = date;
                                  print('confirm $date');
                                },
                                    currentTime: DateTime.now(),
                                    locale: LocaleType.en);
                              },
                              child: Text(
                                'birthday',
                              )),
                        ],
                      ),
                    ),
                    SizedBox(
                      height: 30,
                    ),
                    FadeAnimation(
                      2,
                      InkWell(
                        onTap: () => {
                          // print(
                          //     "useriddd: $userId   birthdayyyy: ${birthday.toString()}"),
                          id = userId,
                          validate(context),
                        },
                        child: Container(
                          height: 50,
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(10),
                            gradient: LinearGradient(
                              colors: [
                                Color.fromRGBO(143, 148, 251, .4),
                                Color.fromRGBO(143, 148, 251, .8),
                              ],
                            ),
                          ),
                          child: Center(
                            child: Text(
                              "Complete data",
                              style: TextStyle(
                                color: Colors.white,
                                fontWeight: FontWeight.bold,
                                fontFamily: 'persianBold',
                                fontSize: 18,
                              ),
                            ),
                          ),
                        ),
                      ),
                    ),
                    SizedBox(
                      height: 20,
                    ),
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

Edit:

after did some change in code I got this error:

Error Code : 1 (SQLITE_ERROR) E/flutter (18587): Caused By : SQL(query) error or missing database. E/flutter (18587): (near "00": syntax error (code 1): , while compiling: UPDATE User SET name = mehrdad, family = dolat, birthday = 1450-12-31 00:00:00.000, mobile = 0936, nationalId = 001 WHERE id = {id: 1}) E/flutter (18587): #################################################################) sql 'UPDATE User SET name = mehrdad, family = dolat, birthday = 1450-12-31 00:00:00.000, mobile = 0936, nationalId = 001 WHERE id = {id: 1}' args []}

updated code :

  Future<User> update(String id, String name, String family, String birthday,
      String mobile, String nationalId) async {
    var dbClient = await db;
    var res = await dbClient.rawQuery(
        'UPDATE $USER_TABLE SET $NAME = $name, $FAMILY = $family, $BIRTHDAY = $birthday, $MOBILE = $mobile, $NATIONAL_ID = $nationalId WHERE id = $id');

    if (res.length > 0) {
      return new User.fromMap(res.first);
    }
    return null;
  }

and in my screen:

  dbHelper.update(
          id.toString(),
          nameController.text,
          familyController.text,
          birthday.toString(),
          mobileController.text,
          nationalIdController.text);

      navigateToUsersList(ctx);

Edit Number 2:

I think we need just one more step to do this:

I do a new change on update method in database helper:

   Future<int> update(String id, String name, String family, String birthday,
      String mobile, String nationalId) async {
    var dbClient = await db;
    return await dbClient.rawUpdate(
        'UPDATE $USER_TABLE SET $NAME = \'$name\', $FAMILY = \'$family\' ,$BIRTHDAY = \'$birthday\', $MOBILE = \'$mobile\' , $NATIONAL_ID = \'$nationalId\' WHERE $ID = ${int.parse(id)}');
  }

and when I try to add an Id for where section I got this error :

[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: FormatException: Invalid radix-10 number (at character 1) E/flutter (21459): {id: 2}

but if I hardcoded id for example where $ID = 2 everything works fine. how I can fix this issue? why {} add beside id? and how I must remove it


Solution

  • after some search and trying I found the solution:

    update method in db_helper:

      Future<int> update(String id, String name, String family, String birthday,
          String mobile, String nationalId) async {
        var dbClient = await db;
        return await dbClient.rawUpdate(
            'UPDATE $USER_TABLE SET $NAME = \'$name\', $FAMILY = \'$family\' ,$BIRTHDAY = \'$birthday\', $MOBILE = \'$mobile\' , $NATIONAL_ID = \'$nationalId\' WHERE $ID = ${int.parse(id)}');
      }
    

    and validate method in Screen:

     validate(BuildContext ctx) async {
        if (nameController.text != "" &&
            familyController.text != "" &&
            nationalIdController.text != "" &&
            mobileController.text != "") {
          final dbHelper = DBHelper();
    
          dbHelper.update(
              id.toString(),
              nameController.text,
              familyController.text,
              birthday.toString(),
              mobileController.text,
              nationalIdController.text);
    
          navigateToUsersList(ctx);
        } else {
          showFlushBar(ctx, "error", "Please fill all fields");
        }
      }