Home Blog Page 20

Flutter Todo App with NodeJS & MongoDB at backend

0
Flutter To-Do App With Nodejs + mongodb at Backend
Flutter To-Do App With Nodejs + mongodb at Backend

Hi Guy’s, In this Flutter Tutorial, We will build a Flutter Todo App with NodeJS & MongoDB at backend. In this article I have covered Fully Functional App with CRUD (Create, Read, Update, Delete) Operation in Flutter Todo Application, The User will be Authenticated using JSON Web Tokens & With JWT Tokens Flutter app used will be kept online.

We will cover everything from setting up Restful API with NODEJS, Integrating Mongodb for database management and creating the Flutter todo app with user authentication.

Complete Video Tutorial on Flutter Todo App with NodeJS & MongoDB at Backend



NodeJS Backend

NodeJS Todo App Setup

npm packages used:

  • bcrypt
  • body-parser
  • express
  • jsonwebtoken
  • mongoose
  • nodemon

NodeJS Project Structure for ToDo app

NodeJS Project Structure for ToDo app
NodeJS Project Structure for ToDo app

Note: How our code execute? The Code Follow

index.js -> app.js -> router -> controller -> service

index.js

const app = require("./app");
const db = require('./config/db')

const port = 3000;

app.listen(port,()=>{
    console.log(`Server Listening on Port http://localhost:${port}`);
})

app.js

const express = require("express");
const bodyParser = require("body-parser")
const UserRoute = require("./routes/user.routes");
const ToDoRoute = require('./routes/todo.router');
const app = express();

app.use(bodyParser.json())

app.use("/",UserRoute);
app.use("/",ToDoRoute);

module.exports = app;

config

db.js

In this file, we have setup our mongodb database connection. This file is been imported in models so whenever model is been used to perform CRUD operation db will get connected automatically and CRUD operation is been performed.

const mongoose = require('mongoose');

const connection = mongoose.createConnection(`mongodb://127.0.0.1:27017/ToDoDB`).on('open',()=>{console.log("MongoDB Connected");}).on('error',()=>{
    console.log("MongoDB Connection error");
});

module.exports = connection;

models

model is nothing but a database model, Here I have made use of mongoose to create a db schema for user collection and todo list collection as below.

user.model.js

In user schema, we are storing user email & password. Note that here password will be get encrypted using bcrypt package before the data gets stored in user db collection.

const db = require('../config/db');
const bcrypt = require("bcrypt");
const mongoose = require('mongoose');
const { Schema } = mongoose;

const userSchema = new Schema({
    email: {
        type: String,
        lowercase: true,
        required: [true, "userName can't be empty"],
        // @ts-ignore
        match: [
            /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/,
            "userName format is not correct",
        ],
        unique: true,
    },
    password: {
        type: String,
        required: [true, "password is required"],
    },
},{timestamps:true});


// used while encrypting user entered password
userSchema.pre("save",async function(){
    var user = this;
    if(!user.isModified("password")){
        return
    }
    try{
        const salt = await bcrypt.genSalt(10);
        const hash = await bcrypt.hash(user.password,salt);

        user.password = hash;
    }catch(err){
        throw err;
    }
});


//used while signIn decrypt
userSchema.methods.comparePassword = async function (candidatePassword) {
    try {
        console.log('----------------no password',this.password);
        // @ts-ignore
        const isMatch = await bcrypt.compare(candidatePassword, this.password);
        return isMatch;
    } catch (error) {
        throw error;
    }
};

const UserModel = db.model('user',userSchema);
module.exports = UserModel;

todo.model.js

In todo collection, we store userId, title, description. Here userId is stored just to know this data belong to which user, so that we can use userId to fetch data only of that particular user.

const db = require('../config/db');
const UserModel = require("./user.model");
const mongoose = require('mongoose');
const { Schema } = mongoose;

const toDoSchema = new Schema({
    userId:{
        type: Schema.Types.ObjectId,
        ref: UserModel.modelName
    },
    title: {
        type: String,
        required: true
    },
    description: {
        type: String,
        required: true
    },
},{timestamps:true});

const ToDoModel = db.model('todo',toDoSchema);
module.exports = ToDoModel;

routes

user.routes.js

In user router, we will handle user registration & login event through which user will be able to create his account into mongodb database using /register api and then get signIn using /login api

const router = require("express").Router();
const UserController = require('../controller/user.controller');

router.post("/register",UserController.register);

router.post("/login", UserController.login);


module.exports = router;

todo.routes.js

In todo routes, we will handle user event from flutter application like user will be able to add his todo data, get all the todo list of a particular signed In user and delete his todo list.

const router = require("express").Router();
const ToDoController = require('../controller/todo.controller')

router.post("/createToDo",ToDoController.createToDo);

router.get('/getUserTodoList',ToDoController.getToDoList)

router.post("/deleteTodo",ToDoController.deleteToDo)

module.exports = router;

controller

In controllers, We have function that handle request & response. Here in request we get parameters requested from frontend i.e. flutter app and response the data from backend to frontend for the requested data to the app.

user.controller.js

In user.controller.js we have 2 functions (register & login).

The register function is used to create account of a user.

The login function helps used to get login into the application.

const UserServices = require('../services/user.service');

exports.register = async (req, res, next) => {
    try {
        console.log("---req body---", req.body);
        const { email, password } = req.body;
        const duplicate = await UserServices.getUserByEmail(email);
        if (duplicate) {
            throw new Error(`UserName ${email}, Already Registered`)
        }
        const response = await UserServices.registerUser(email, password);

        res.json({ status: true, success: 'User registered successfully' });


    } catch (err) {
        console.log("---> err -->", err);
        next(err);
    }
}

exports.login = async (req, res, next) => {
    try {

        const { email, password } = req.body;

        if (!email || !password) {
            throw new Error('Parameter are not correct');
        }
        let user = await UserServices.checkUser(email);
        if (!user) {
            throw new Error('User does not exist');
        }

        const isPasswordCorrect = await user.comparePassword(password);

        if (isPasswordCorrect === false) {
            throw new Error(`Username or Password does not match`);
        }

        // Creating Token

        let tokenData;
        tokenData = { _id: user._id, email: user.email };
    

        const token = await UserServices.generateAccessToken(tokenData,"secret","1h")

        res.status(200).json({ status: true, success: "sendData", token: token });
    } catch (error) {
        console.log(error, 'err---->');
        next(error);
    }
}

todo.controller.js

In todo controller, We have 3 function that perform different task (createToDo, getTodoList, deleteToDo).

const ToDoService = require('../services/todo.service');

exports.createToDo =  async (req,res,next)=>{
    try {
        const { userId,title, desc } = req.body;
        let todoData = await ToDoService.createToDo(userId,title, desc);
        res.json({status: true,success:todoData});
    } catch (error) {
        console.log(error, 'err---->');
        next(error);
    }
}

exports.getToDoList =  async (req,res,next)=>{
    try {
        const { userId } = req.body;
        let todoData = await ToDoService.getUserToDoList(userId);
        res.json({status: true,success:todoData});
    } catch (error) {
        console.log(error, 'err---->');
        next(error);
    }
}

exports.deleteToDo =  async (req,res,next)=>{
    try {
        const { id } = req.body;
        let deletedData = await ToDoService.deleteToDo(id);
        res.json({status: true,success:deletedData});
    } catch (error) {
        console.log(error, 'err---->');
        next(error);
    }
}

services

In services, all the database operation happens like fetching, Insertion, Deletion.

user.service.js

const UserModel = require("../models/user.model");
const jwt = require("jsonwebtoken");

class UserServices{
 
    static async registerUser(email,password){
        try{
                console.log("-----Email --- Password-----",email,password);
                
                const createUser = new UserModel({email,password});
                return await createUser.save();
        }catch(err){
            throw err;
        }
    }

    static async getUserByEmail(email){
        try{
            return await UserModel.findOne({email});
        }catch(err){
            console.log(err);
        }
    }

    static async checkUser(email){
        try {
            return await UserModel.findOne({email});
        } catch (error) {
            throw error;
        }
    }

    static async generateAccessToken(tokenData,JWTSecret_Key,JWT_EXPIRE){
        return jwt.sign(tokenData, JWTSecret_Key, { expiresIn: JWT_EXPIRE });
    }
}

module.exports = UserServices;

todo.service.js

const { deleteToDo } = require("../controller/todo.controller");
const ToDoModel = require("../models/todo.model");

class ToDoService{
    static async createToDo(userId,title,description){
            const createToDo = new ToDoModel({userId,title,description});
            return await createToDo.save();
    }

    static async getUserToDoList(userId){
        const todoList = await ToDoModel.find({userId})
        return todoList;
    }

   static async deleteToDo(id){
        const deleted = await ToDoModel.findByIdAndDelete({_id:id})
        return deleted;
   }
}

module.exports = ToDoService;

Clone NodeJS backend Todo App from GitHub

You can clone the backend code for Todo App with NodeJS from my Github repository

https://github.com/RajatPalankar8/nodejs_backend_todo.git



Flutter FrontEnd

Creating Todo app in flutter with NodeJS & mongodb at backend

flutter dependencies used:

Open pubspec.yaml file and add this dependencies:

dependencies:
  flutter:
    sdk: flutter
  velocity_x:
  http:
  shared_preferences:
  jwt_decoder:
  flutter_slidable:

Flutter Todo App Project Structure

flutter todo app project structure
flutter todo app project structure

applogo.dart

Here I have create a common page to show a app logo wherever required.

import 'package:flutter/material.dart';
import 'package:velocity_x/velocity_x.dart';

class CommonLogo extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Image.network("https://pluspng.com/img-png/avengers-logo-png-avengers-logo-png-1376.png",width: 100,),
        "To-Do App".text.xl2.italic.make(),
        "Make A List of your task".text.light.white.wider.lg.make(),
      ],
    );
  }
}

config.dart

In config file, I have Listed all the url that point to nodejs backend API.

final url = 'http://192.168.29.239:3000/';
final registration = url + "registration";
final login = url + 'login';
final addtodo = url + 'storeTodo';
final getToDoList = url + 'getUserTodoList';
final deleteTodo = url + 'deleteTodo';

main.dart

From main page, user will get navigated to respective page depending on the state of an app. Here If user has login into the app I have stored the user login details inside a token variable which is been stored in sharedPreferences. The Token is been generated by our backend using JWT token which contain expire time.

So here if token don’t exist then it means that the user is new and yet to login so we simply navigate the user to login page.

If Token Exist, It will have a Expire time we make use of JWT decoder to decode the token and check if it is expired or not, then if the token is expired then navigate the user to login page else if token is not expired and still valid then navigate the user to dashboad page.

import 'package:flutter/material.dart';
import 'package:flutter_todo_app/dashboard.dart';
import 'package:jwt_decoder/jwt_decoder.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'loginPage.dart';



void main() async {
   WidgetsFlutterBinding.ensureInitialized();
   SharedPreferences prefs = await SharedPreferences.getInstance();
  runApp(MyApp(token: prefs.getString('token'),));
}

class MyApp extends StatelessWidget {

  final token;
  const MyApp({
    @required this.token,
    Key? key,
}): super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(

        primaryColor: Colors.black,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: (token != null && JwtDecoder.isExpired(token) == false )?Dashboard(token: token):SignInPage()
    );
  }
}

registration.dart

In registration page, user will be able to create his account into flutter todo app and register himself. Here he has to fill his email & password to create his account.

flutter todo app registration page
flutter todo app registration page
import 'dart:convert';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:velocity_x/velocity_x.dart';
import 'applogo.dart';
import 'loginPage.dart';
import 'package:http/http.dart' as http;
import 'config.dart';

class Registration extends StatefulWidget {
  @override
  _RegistrationState createState() => _RegistrationState();
}

class _RegistrationState extends State<Registration> {

  TextEditingController emailController = TextEditingController();
  TextEditingController passwordController = TextEditingController();
  bool _isNotValidate = false;

  void registerUser() async{
    if(emailController.text.isNotEmpty && passwordController.text.isNotEmpty){

      var regBody = {
        "email":emailController.text,
        "password":passwordController.text
      };

      var response = await http.post(Uri.parse(registration),
      headers: {"Content-Type":"application/json"},
      body: jsonEncode(regBody)
      );

      var jsonResponse = jsonDecode(response.body);

      print(jsonResponse['status']);

      if(jsonResponse['status']){
        Navigator.push(context, MaterialPageRoute(builder: (context)=>SignInPage()));
      }else{
        print("SomeThing Went Wrong");
      }
    }else{
      setState(() {
        _isNotValidate = true;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Container(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height,
          decoration: BoxDecoration(
            gradient: LinearGradient(
                colors: [const Color(0XFFF95A3B),const Color(0XFFF96713)],
                begin: FractionalOffset.topLeft,
                end: FractionalOffset.bottomCenter,
                stops: [0.0,0.8],
                tileMode: TileMode.mirror
            ),
          ),
          child: Center(
            child: SingleChildScrollView(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  CommonLogo(),
                  HeightBox(10),
                  "CREATE YOUR ACCOUNT".text.size(22).yellow100.make(),
                  TextField(
                    controller: emailController,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                        filled: true,
                        fillColor: Colors.white,
                        errorStyle: TextStyle(color: Colors.white),
                        errorText: _isNotValidate ? "Enter Proper Info" : null,
                        hintText: "Email",
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.all(Radius.circular(10.0)))),
                  ).p4().px24(),
                  TextField(
                    controller: passwordController,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                        suffixIcon: IconButton(icon: Icon(Icons.copy),onPressed: (){
                          final data = ClipboardData(text: passwordController.text);
                          Clipboard.setData(data);
                        },),
                        prefixIcon: IconButton(icon: Icon(Icons.password),onPressed: (){
                          String passGen =  generatePassword();
                          passwordController.text = passGen;
                          setState(() {

                          });
                        },),
                        filled: true,
                        fillColor: Colors.white,
                        errorStyle: TextStyle(color: Colors.white),
                        errorText: _isNotValidate ? "Enter Proper Info" : null,
                        hintText: "Password",
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.all(Radius.circular(10.0)))),
                  ).p4().px24(),
                  HStack([
                    GestureDetector(
                      onTap: ()=>{
                        registerUser()
                      },
                        child: VxBox(child: "Register".text.white.makeCentered().p16()).green600.roundedLg.make().px16().py16(),
                    ),
                  ]),
                  GestureDetector(
                    onTap: (){
                      print("Sign In");
                      Navigator.push(context, MaterialPageRoute(builder: (context)=>SignInPage()));
                    },
                    child: HStack([
                      "Already Registered?".text.make(),
                      " Sign In".text.white.make()
                    ]).centered(),
                  )
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

String generatePassword() {
  String upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  String lower = 'abcdefghijklmnopqrstuvwxyz';
  String numbers = '1234567890';
  String symbols = '!@#\$%^&*()<>,./';

  String password = '';

  int passLength = 20;

  String seed = upper + lower + numbers + symbols;

  List<String> list = seed.split('').toList();

  Random rand = Random();

  for (int i = 0; i < passLength; i++) {
    int index = rand.nextInt(list.length);
    password += list[index];
  }
  return password;
}

loginPage.dart

Once the user create his account then he can make use of his email & password to login into the todo flutter application. If the login detail entered by user is correct then the user get navigated to dashboard page.

flutter todo app login page
flutter todo app login page
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_todo_app/dashboard.dart';
import 'package:flutter_todo_app/registration.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:velocity_x/velocity_x.dart';
import 'applogo.dart';
import 'package:http/http.dart' as http;
import 'config.dart';

class SignInPage extends StatefulWidget {
  @override
  _SignInPageState createState() => _SignInPageState();
}

class _SignInPageState extends State<SignInPage> {
  TextEditingController emailController = TextEditingController();
  TextEditingController passwordController = TextEditingController();
  bool _isNotValidate = false;
  late SharedPreferences prefs;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    initSharedPref();
  }

  void initSharedPref() async{
    prefs = await SharedPreferences.getInstance();
  }

  void loginUser() async{
    if(emailController.text.isNotEmpty && passwordController.text.isNotEmpty){

      var reqBody = {
        "email":emailController.text,
        "password":passwordController.text
      };

      var response = await http.post(Uri.parse(login),
          headers: {"Content-Type":"application/json"},
          body: jsonEncode(reqBody)
      );

      var jsonResponse = jsonDecode(response.body);
      if(jsonResponse['status']){
          var myToken = jsonResponse['token'];
          prefs.setString('token', myToken);
          Navigator.push(context, MaterialPageRoute(builder: (context)=>Dashboard(token: myToken)));
      }else{
        print('Something went wrong');
      }

    }
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Container(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height,
          decoration: BoxDecoration(
            gradient: LinearGradient(
                colors: [const Color(0XFFF95A3B),const Color(0XFFF96713)],
                begin: FractionalOffset.topLeft,
                end: FractionalOffset.bottomCenter,
                stops: [0.0,0.8],
                tileMode: TileMode.mirror
            ),
          ),
          child: Center(
            child: SingleChildScrollView(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  CommonLogo(),
                  HeightBox(10),
                  "Email Sign-In".text.size(22).yellow100.make(),

                  TextField(
                    controller: emailController,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                        filled: true,
                        fillColor: Colors.white,
                        hintText: "Email",
                        errorText: _isNotValidate ? "Enter Proper Info" : null,
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.all(Radius.circular(10.0)))),
                  ).p4().px24(),
                  TextField(
                    controller: passwordController,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                        filled: true,
                        fillColor: Colors.white,
                        hintText: "Password",
                        errorText: _isNotValidate ? "Enter Proper Info" : null,
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.all(Radius.circular(10.0)))),
                  ).p4().px24(),
                  GestureDetector(
                    onTap: (){
                        loginUser();
                    },
                    child: HStack([
                      VxBox(child: "LogIn".text.white.makeCentered().p16()).green600.roundedLg.make(),
                    ]),
                  ),
                ],
              ),
            ),
          ),
        ),
        bottomNavigationBar: GestureDetector(
          onTap: (){
            Navigator.push(context, MaterialPageRoute(builder: (context)=>Registration()));
          },
          child: Container(
              height: 25,
              color: Colors.lightBlue,
              child: Center(child: "Create a new Account..! Sign Up".text.white.makeCentered())),
        ),
      ),
    );
  }
}

dashboard.dart

Once the user successfully get login into flutter todo list app, From the dashboard page he will be able to perform 3 task i.e. add todo, delete todo item, and get all the todo data.

add todo list: To add Todo list use has to click on floating action button that popup a dialog box, In dialog box we have 2 Text Field to Enter title & description of todo item.

flutter todo add item
flutter todo add item

dashboard todo List: In dashboard we will show all the todo list created by user in a ListView.

Flutter show list of todo list item in listview
Flutter show list of todo list item in listview

delete todo item: To delete item from the todo listview, user has to select the listview listtile and slide to see an option to delete the item.

flutter todo list slide to delete item
flutter todo list slide to delete item
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:jwt_decoder/jwt_decoder.dart';
import 'package:velocity_x/velocity_x.dart';
import 'package:http/http.dart' as http;
import 'config.dart';
import 'package:flutter_slidable/flutter_slidable.dart';

class Dashboard extends StatefulWidget {
  final token;
  const Dashboard({@required this.token,Key? key}) : super(key: key);

  @override
  State<Dashboard> createState() => _DashboardState();
}

class _DashboardState extends State<Dashboard> {

  late String userId;
  TextEditingController _todoTitle = TextEditingController();
  TextEditingController _todoDesc = TextEditingController();
  List? items;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    Map<String,dynamic> jwtDecodedToken = JwtDecoder.decode(widget.token);

    userId = jwtDecodedToken['_id'];
    getTodoList(userId);
  }

  void addTodo() async{
    if(_todoTitle.text.isNotEmpty && _todoDesc.text.isNotEmpty){

      var regBody = {
        "userId":userId,
        "title":_todoTitle.text,
        "desc":_todoDesc.text
      };

      var response = await http.post(Uri.parse(addtodo),
          headers: {"Content-Type":"application/json"},
          body: jsonEncode(regBody)
      );

      var jsonResponse = jsonDecode(response.body);

      print(jsonResponse['status']);

      if(jsonResponse['status']){
        _todoDesc.clear();
        _todoTitle.clear();
        Navigator.pop(context);
        getTodoList(userId);
      }else{
        print("SomeThing Went Wrong");
      }
    }
  }

  void getTodoList(userId) async {
    var regBody = {
      "userId":userId
    };

    var response = await http.post(Uri.parse(getToDoList),
        headers: {"Content-Type":"application/json"},
        body: jsonEncode(regBody)
    );

    var jsonResponse = jsonDecode(response.body);
    items = jsonResponse['success'];

    setState(() {

    });
  }

  void deleteItem(id) async{
    var regBody = {
      "id":id
    };

    var response = await http.post(Uri.parse(deleteTodo),
        headers: {"Content-Type":"application/json"},
        body: jsonEncode(regBody)
    );

    var jsonResponse = jsonDecode(response.body);
    if(jsonResponse['status']){
      getTodoList(userId);
    }

  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.lightBlueAccent,
       body: Column(
         crossAxisAlignment: CrossAxisAlignment.start,
         children: [
           Container(
             padding: EdgeInsets.only(top: 60.0,left: 30.0,right: 30.0,bottom: 30.0),
             child: Column(
               crossAxisAlignment: CrossAxisAlignment.start,
               children: [
                 CircleAvatar(child: Icon(Icons.list,size: 30.0,),backgroundColor: Colors.white,radius: 30.0,),
                 SizedBox(height: 10.0),
                 Text('ToDo with NodeJS + Mongodb',style: TextStyle(fontSize: 30.0,fontWeight: FontWeight.w700),),
                 SizedBox(height: 8.0),
                 Text('5 Task',style: TextStyle(fontSize: 20),),

               ],
             ),
           ),
           Expanded(
             child: Container(
               decoration: BoxDecoration(
                   color: Colors.white,
                   borderRadius: BorderRadius.only(topLeft: Radius.circular(20),topRight: Radius.circular(20))
               ),
               child: Padding(
                 padding: const EdgeInsets.all(8.0),
                 child: items == null ? null : ListView.builder(
                     itemCount: items!.length,
                     itemBuilder: (context,int index){
                       return Slidable(
                         key: const ValueKey(0),
                         endActionPane: ActionPane(
                           motion: const ScrollMotion(),
                           dismissible: DismissiblePane(onDismissed: () {}),
                           children: [
                             SlidableAction(
                               backgroundColor: Color(0xFFFE4A49),
                               foregroundColor: Colors.white,
                               icon: Icons.delete,
                               label: 'Delete',
                               onPressed: (BuildContext context) {
                                 print('${items![index]['_id']}');
                                 deleteItem('${items![index]['_id']}');
                               },
                             ),
                           ],
                         ),
                         child: Card(
                           borderOnForeground: false,
                           child: ListTile(
                             leading: Icon(Icons.task),
                             title: Text('${items![index]['title']}'),
                             subtitle: Text('${items![index]['desc']}'),
                             trailing: Icon(Icons.arrow_back),
                           ),
                         ),
                       );
                     }
                 ),
               ),
             ),
           )
         ],
       ),
      floatingActionButton: FloatingActionButton(
        onPressed: () =>_displayTextInputDialog(context) ,
        child: Icon(Icons.add),
        tooltip: 'Add-ToDo',
      ),
    );
  }

  Future<void> _displayTextInputDialog(BuildContext context) async {
    return showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text('Add To-Do'),
            content: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                TextField(
                  controller: _todoTitle,
                  keyboardType: TextInputType.text,
                  decoration: InputDecoration(
                      filled: true,
                      fillColor: Colors.white,
                      hintText: "Title",
                      border: OutlineInputBorder(
                          borderRadius: BorderRadius.all(Radius.circular(10.0)))),
                ).p4().px8(),
                TextField(
                  controller: _todoDesc,
                  keyboardType: TextInputType.text,
                  decoration: InputDecoration(
                      filled: true,
                      fillColor: Colors.white,
                      hintText: "Description",
                      border: OutlineInputBorder(
                          borderRadius: BorderRadius.all(Radius.circular(10.0)))),
                ).p4().px8(),
                ElevatedButton(onPressed: (){
                  addTodo();
                  }, child: Text("Add"))
              ],
            )
          );
        });
  }
}

Clone Flutter Todo App Source Code from my GitHub Repository

https://github.com/RajatPalankar8/flutter_todo__with_nodejs.git



MongoDB database Collection

This is how data get stored into mongodb database when user use flutter application to store his todo list into app.

mongodb todo list database for flutter app
mongodb compose show todo collection of users

Replace or Remove a string from a given String in Dart Flutter

0
dart string methods
substring in flutter

In Flutter App development where we use dart language, we can replace or remove substrings from the original string using dart In-Built String Methods:

  • replaceAll()
  • replaceAllMapped()
  • replaceFirst()
  • replaceFirstMapped()
  • replaceRange()

Now, let’s use each of this dart string method to replace string.

Dart replaceAll() method

In below Example, We are use replaceAll() function, so what this will do is it will replace all the occurences of word/substring “easy” with “difficult” in the given string.

void main() {
  String str = "This homework is very easy";
  String substr = "easy";
  String replace = "difficult";

  String newStr = str.replaceAll(substr, replace);
  print(newStr);
}

Output of above dart code

This homework is very difficult

Dart replaceRange() method

In below Example, I want to replace range of index from the given string. From example I have a String sentence “The bird is sitting on the branch, The bird is Looking Beautiful”. here I want to replace “bird” with “sparrow” by using range/index of string.

the replaceRange() method accepts 3 parameter replaceRange(startIndex , EndIndex, replacement string) as shown below:

void main() {
  String str = "The bird is sitting on the branch, The bird is Looking Beautiful";
  
  String newStr = str.replaceRange(4, 8, "sparrow");
  print(newStr);
}

Output of above dart code

The sparrow is sitting on the branch, The bird is Looking Beautiful

Dart replaceAllMapped() method

Suppose I want to replace all the words that has 8 letters in the given string, then at this time I can make use of replaceAllMapped() function.

void main() {
  String str =
      "I Like to play fortnite game and Learn Programming from Proto Coders Point";

  // Here I am using Regular Expression to match 8 letter word in given string 
  // and then replace it with _________
  var pattern = RegExp(r'\b\w{8}\b');
  String replacement = "________";

  String newStr = str.replaceAllMapped(pattern, (match) => replacement);
  print(newStr); 
}

In Above code I am using Regular Expression to match 8 letter word in given string and then replace it with _____.

Output of above dart code

I Like to play ________ game and Learn Programming from Proto Coders Point

Dart replaceFirst() Method

Suppose you want to replace only the first word that occurs in the given string, Let’s say I have sentence “don’t have a bad day have a great day, because bad day will come and go”. Here I want to only change first occurrence of word bad, In such situation I can make use of dart replaceFirst() methon.

void main() {
  String str =
      "don't have a bad day have a great day";
  String substr = "bad";
  String replacement = "good";

  String newStr = str.replaceFirst(substr, replacement);
  print(newStr);
}

Output of above dart code

don't have a good day have a great day

Dart replaceFirstMapped() method

In below example, I have a sentence “I Like to play fortnite game, fortnite is my favourite game and Learn Programming from Proto Coders Point”, which contain 8 letter word “fortnite” for 2 times, I want to replace only the first occurrences of it.

void main() {
  String str =
      "I Like to play fortnite game, fortnite is my favourite game and Learn Programming from Proto Coders Point";

  // Here I am using Regular Expression to match 8 letter word in given string 
  // and then replace it with _________
  var pattern = RegExp(r'\b\w{8}\b');
  String replacement = "________";

  String newStr = str.replaceFirstMapped(pattern, (match) => replacement);
  print(newStr); 
}

Output of above dart code

I Like to play ________ game, fortnite is my favourite game and Learn Programming from Proto Coders Point

To remove any word from a given string then simple pass an empty replacement (“”)

str.replaceAll("bad",""); // by doing this bad word from a given string will get removed.

Install Go Language in Window – Hello World Program in goLang

0
how to install go language
go language

Let’s Download Go installed from official site

  1. Go to the official Go website and download the appropriate installation file for your operating system.
  2. Run the installer and follow the instructions to complete the installation.
install go language in windows
install go language in windows
install go language in windows

Hello World Program in Go Language

1. Create a Folder in Desktop or anywhere.


2. Open the Folder in any Text Editor (Sublime Text or VSCode).


3. Create a file names “hello_world.go”, Here go is golang file extension.

paste below hello world code

package main

import "fmt"

func main() {
    fmt.Println("Hello World!")
}

you name get error near package main saying “go.mod file not found”, It’s because go language module is not initialized to hello_world.go file, To add the file into go.mod run below cmd as shown in step 4.


4. Open Terminal in IDE

go mod init hello_world.go

This will create a go.mod file and add the file into it.


go language hello world program

run go program go run hello.go

create a executable file go build hello_world.go

run the exe file .\hello_world.exe

Video on Installing Go lang and hello world program

get String from ASCII code or vice versa in flutter dart

0
String to ASCII or ASCII to String in dart

Hi Guys, In this dart article let’s checkout How to get ASCII code from a Character or String from a ASCII code in dart language (will also work in Flutter programming).

What is ASCII?

ASCII stands from American Standard Code from Information Interchange, ASCII is a encoding standard character that use 7 bit binary code basically to represent 128 possible character, which include characters like digits, letters, punctuation marks & control Code.

Eg:- A ASCII code for letter capital ‘A’ is 65 & for small ‘a’ = 97, Likewise ASCII code for digit 0 is 48.

ASCII Code Chart

Download ascii chart from commons.wikimedia.org

Getting String from ASCII code in dart

Example 1: ASCII to String in dart

void main() {
  var asciiCode = 98;

  String mString = String.fromCharCode(asciiCode);

  print(mString); // b

}

Example 2: ASCII to String in dart

void main() {
  List<int> asciiCodes = [
    45,
    102,
    100,
    99,
    98,
    101,
    111,
    67,
    88,
    128,
    99,
    103,
    109
  ];
  String message = '';
  for (int code in asciiCodes) {
    message += String.fromCharCode(code);
  }
  print(message);
}

Output

-fdcbeoCXcgm

Getting ASCII Code from String in dart

Example 1: String to ASCII in dart

void main() {   
  String mString2 = 'a';

  var ascii = mString2.codeUnitAt(0);
  print(ascii);  // 97

}

Example 2: String to ASCII in dart

void main() {
  String message = "This is Example to get ASCII code from String";
  List<int> asciiCodes = [];
  for (int i = 0; i < message.length; i++) {
    asciiCodes.add(message.codeUnitAt(i));
  }
  print(asciiCodes);
}

Output

[84, 104, 105, 115, 32, 105, 115, 32, 69, 120, 97, 109, 112, 108, 101, 32, 116, 111, 32, 103, 101, 116, 32, 65, 83, 67, 73, 73, 32, 99, 111, 100, 101, 32, 102, 114, 111, 109, 32, 83, 116, 114, 105, 110, 103]

How to set Default TimeZone in NodeJS

0
How to Set Default Time Zone in NodeJS
Time Zone in nodejs

Hi Guys, In this NodeJS article will work on timeZone, Basically will learn how to set default time zone in nodejs project.

This NodeJs Tutorial, we will learn the 2 ways by which we can set default timezone in nodejs applications.

2 ways to set default timezone in nodejs javascript

  1. Modifying TZ Environment variable.
  2. Using 3rd party package set-tz.

1. Defining default time zone using TZ Environment

To set time zone at runtime do this:

process.env.TZ = 'Etc/Universal'; // UTC +00:00
console.log(new Date().toString())


or 

process.env.TZ = 'Asia/Kolkata'; // UTC +05:30  Indian Standard TimeZone.
console.log(new Date().toString())

Output

Fri Feb 04 2022 06:10:01 GMT+0000 (Coordinated Universal Time)

Setting Time Zone default in package.json file

The TZ variable can also be set through package.json file:

"scripts": {
    "start": "node TZ=Asia/Kolkata ./build/index.js",
    "dev": "TZ=Asia/Kolkata nodemon ./src/index.ts",
},

2. using 3rd party packages i.e set-tz

In NodeJS There are various package library using which we can set default time zone, we will make use of set-tz.

Install set-tz in your node project

npm i set-tz @types/set-tz

How to use set-tz package

First we need to import set-tz from set-tz package where you want to apply default timezone, then by using setTZ() method you can pass which time zone you want to set (in my case I have set Asia/Kolkata)

import setTZ from 'set-tz';
setTZ('Asia/Kolkata')

console.log(new Date().toString())

Output

Fri Feb 04 2022 01:22:59 GMT+0530 

Conclusion

In this NodeJS article, We shown 2 technique through which we can easily set Time Zone for our NodeJS Project.