Home Blog Page 4

Downloading Files/Media in Flutter – flutter_media_downloader

0
How to Implement Download Option in Flutter
How to Implement Download Option in Flutter

Downloading files in flutter is must required feature to be added into any flutter where their are document or any kind of files that the user want to download & store if for later usage.

Media download in flutter is seamless bring media content to your flutter application.

Flutter Downloader – How to implement files downloading in flutter application

To add download feature in flutter application we will make use of a package called flutter_media_downloader, This package has capability of downloading any kind of files like, Images, Videos, Document like pdf, docx etc.

Video Tutorial

Download Files in Flutter

1. Create a Flutter Project or Open Existing

Create a new Flutter Project or Open any Existing Flutter in your favorite IDE VSCode or Android Studio. I use android studio for building flutter application.


2. Add flutter_media_downloader package.

In your flutter project open pubspec.yaml files and under dependencies section add the flutter media downloader package as shown below

#screenshot

and then run flutter pub get to download the package as external libraries.


3. Add permission for Android & IOS

As the files or media get downloaded from Internet We need Internet Permission & to store the downloaded files locally in mobile devices we need Storage Permission.

Android: Open AndroidManifest.xml file and add below lines

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

iOS: Open info.plist files and add below lines

<dict>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>We need access to Photo library</string>
</dict>

4. How to Implement flutter media downloader

Complete Source Code

main.dart

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

void main() async{
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(

        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _flutterDownload = MediaDownload();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () async{
            _flutterDownload.downloadMedia(context, 'https://32net.id/bukaheula/share/otQ9czP4vdLTyiJdmlAXaNK76xKtu38ykwnTm8q0.pdf');
          }, child: Text('Download'),

        ),
      ),
    );
  }
}

Star Pattern Program – Print RAM Star Pattern in JavaScript

0
Print RAM Star Pattern in JavaScript

Source Code

function printStarPattern(character) {
  const patterns = {
    'R': [
      '*****',
      '*   *',
      '*****',
       '* *',
      '*  *',
    ],
    'A': [
      '  *  ',
      ' * * ',
      '*   *',
       '  *****',
      ' *   *',
    ],
    'M': [
      '*   *',
      '** **',
      '* * *',
      '*   *',
      '*   *',
    ],
  };

  if (patterns[character]) {
    return patterns[character];
  } else {
    console.log('Pattern not defined for character: ' + character);
    return [];
  }
}

function printRAM() {
  const word = ['R', 'A', 'M'];

  for (let row = 0; row < 5; row++) {
    let line = '';
    for (let i = 0; i < word.length; i++) {
      const patternLines = printStarPattern(word[i]);
      line += patternLines[row] + '  ';
    }
    console.log(line);
  }
}

// Call the function to print "RAM" side by side
printRAM();

Result

print RAM star pattern in javascript

Form Validation – Naughty Form a Dynamic Validation

0
html form validation

This Web page represents a Form validation in a naughty way, Where the button moves right or left if the user has not filled the form and he tried to click on the button to submit.

html form validation

Source Code

<html>

<head>
    <style>
        .outer {
            margin: auto;
            height: 300px;
            width: 400px;
            border: 2px solid black;
            position: relative
        }

        p {
            margin-left: 80px;
        }

        .in {
            margin-left: 80px;
            padding: 10px
        }

        #bt {
            margin-top: 20px;
            position: absolute;
            left: 150px;
        }

        #bt:hover {
            background: green;
            font-size: 13px;
            cursor: pointer;
            color: white;
        }
    </style>
    <script>
        function fa() {
            if (email.value == "" || pass.value == "") {
                f()
                document.getElementById("email").style.border = "2px solid red"
                document.getElementById("pass").style.border = "2px solid red"
                bt.value = "Pahila data dal bay"
            }
            else {
                document.getElementById("email").style.border = "2px solid green"
                document.getElementById("pass").style.border = "2px solid green"
                bt.value = "Ha thik ahe ata"
                bt.style.left = "120px";
            }
        }
        flag = 1
        function f() {
            if (flag == 1) {
                bt.style.left = "210px"
                flag = 2
            }
            else if (flag == 2) {
                bt.style.left = "80px"
                flag = 1
            }
        } 
    </script>
</head>

<body>
    <div class="outer">
        <h1 style="text-align:center">Legend Validate form</h1>
        <p>Enter Email</p>
        <input class="in" type="text" placeholder="Email" id="email" />
        <p>Enter Password</p>
        <input class="in" type="password" placeholder="Password" id="pass" />
        <br>
        <input type="submit" onmouseenter="fa()" onclick="alert('Form Sumbitted..!')" id="bt" />

    </div>

</body>


</html>

Let’s break down the above code in parts and explain the code:

HTML Structure:

<head> Section: In Head we have <style> tag where we define CSS, and <script> we have javascript code where we define function.

CSS Styling:

The CSS styles define the appearance of the form components.

  • .outer: Represents the outer container with specific styling like margin, height, width, border, and relative positioning.
  • p: Applies styling to paragraphs within the form.
  • .in: Applies styling to input elements within the form.
  • #bt: Applies styling to the submit button with specific positioning, margin, and hover effects.

JavaScript:

The <script> tag includes JavaScript functions that add user event to the form like user hover over button to click it.

fa(): This function is called when the mouse hover on the submit button (onmouseenter). It checks if the email and password fields are empty. If either is empty, it calls the function f() and changes the border color of the corresponding input fields to red. It also updates the button text.

f(): This function is used to toggle the position of the submit button (#bt) between two positions. It is invoked when the email and password fields are empty.

HTML Body:

Form Elements:

  • <div class="outer">: Represents the outer container of the form.
  • <h1>: Displays a heading for the form.
  • <p>: Represents paragraphs for the email and password input fields.
  • <input>: Defines input fields for email and password with specific IDs (email and pass).
  • <input type="submit">: Represents the submit button with an onmouseenter event calling the fa() function and an onclick event displaying an alert. The button has the ID bt.

Summary:

In summary, This code is for fun and practicing HTML, CSS and JS for beginners by creating a form with a dynamic submit button that moves when form is empty and use tries to click on the button by hovering. The JavaScript functions are used for form validation, changing button positions, and updating styles based on user interactions. The form includes fields for email and password, and the submit button triggers JavaScript functions to validate the form and provide visual feedback to the user.

Digital + Analog Clock using HTML, CSS and JS

0
Building a Digital Analog Clock
Building a Digital + Analog Clock

Hi Welcome to Proto Coders Point, In this tutorial, we’ll building a simple stylish Digital + analog clock using HTML, CSS, and JS. This clock features distinct hour, minute, and second hands will show a numerical indicators where will show current hours, minute & second as a hand of the clock, providing a visually appealing and functional timekeeping display as animation.

Have a look at below gif image how our clock will look

Source Code

<!DOCTYPE html>
<html>
<head>
  <title>Simple Clock with Lines</title>
  <script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>
  <style>
    #clock {
      position: relative;
      width: 400px;
      height: 400px;
      margin: 50px auto;
      font-size: 18px;
      border:solid
    }
    .hour-line, .minute-line, .second-line {
      position: absolute;
      transform-origin: 50% 100%;
      padding-bottom:15%;
      left:50%;
    }
    .hour-line {
      width: 6px;
      height: 60px;
      top: 90px;
    }
    .minute-line {
      width: 4px;
      height: 80px;
      top: 40px;
    }
    .second-line {
      width: 2px;
      height: 100px;
      top: 25px;
    }
    
  </style>
</head>
<body>

<div id="clock">
  <div class="hour-line" id="hourLine">
    <div class="clock_number">00</div>
    <div class="clock_number">00</div>
    <div class="clock_number">00</div>
    <div class="clock_number">00</div>
  </div>
  <div class="minute-line" id="minuteLine">
    <div class="clock_number">00</div>
    <div class="clock_number">00</div>
    <div class="clock_number">00</div>
    <div class="clock_number">00</div>
    <div class="clock_number">00</div>
    <div class="clock_number">00</div>
    <div class="clock_number">00</div>

  </div>
  <div class="second-line" id="secondLine">
    <div class="clock_number">00</div>
    <div class="clock_number">00</div>
    <div class="clock_number">00</div>
    <div class="clock_number">00</div>
    <div class="clock_number">00</div>
    <div class="clock_number">00</div>
    <div class="clock_number">00</div>
    
  </div>
</div>

<script>
  function updateClock() {
    const now = new Date();
    const hours = now.getHours() % 12 || 12;
    const minutes = now.getMinutes();
    const seconds = now.getSeconds();

    // Calculate angles for hour, minute, and second hands
    const hourAngle = (hours % 12) * 30 + minutes * 0.5;
    const minuteAngle = minutes * 6;
    const secondAngle = seconds * 6;

    // Rotate the lines based on the calculated angles
    $("#hourLine")
     .css("transform", `rotate(${hourAngle}deg)`)
     .children(".clock_number")
     .html(hours)
     .css("transform", `rotate(${-hourAngle}deg)`);

     $("#minuteLine")
  .css("transform", `rotate(${minuteAngle}deg)`)
  .children(".clock_number")
  .html(minutes)
  .css("transform", `rotate(${-minuteAngle}deg)`);    

  $("#secondLine")
  .css("transform", `rotate(${secondAngle}deg)`)
  .children(".clock_number")
  .html(seconds)
  .css("transform", `rotate(${-secondAngle}deg)`);
  }

  // Update the clock every second
  setInterval(updateClock, 1000);

  // Initial call to display the clock immediately
  updateClock();
</script>

</body>
</html>

Above Source Code Explanation

HTML Structure

Let’s start with the HTML structure. The clock is contained within a <div> element with the ID “clock” . Within this div, we have three child div’s which classes named a “hour-line,”minute-line,” and “second-line,”. This 3 div.’s representing the hour, minute, and second hands of the clock, respectively. Additionally, within each line div, there are child div which classes names as “clock_number” to display numerical indicators.


CSS Styling

The CSS code is used to give styling and appearance to the clock design. The clock will have a square shape border, and each hand (hour, minute, and second) is represented by a digital number line with a specific dimensions and positions a the center of the square border. The transform-origin property ensures that the rotation occurs around the base of each line.

JavaScript and jQuery

The JavaScript code is used to update the clock’s hands based on the current time. For this we have a function updateClock that retrieves the current hour, minute, and second and perform calculation for each hand rotations in a proper angle for each hand. The angles we get is then applied using jQuery to rotate the lines. The numerical indicators are updated accordingly.

The setInterval function is used to call the updateClock function every second, ensuring that the clock hands are continuously updated in real-time.

Flutter URL Shortener Project with Source Code

0
Flutter url shortener project

Hi Guy’s Welcome to Proto Coders Point. It this fast growing digital era the importance of concise and shareable URL’s cannot be overstated. If you are trying to make you web address URL manageable or want to share the link of any content on social media or want to embed the URL in a email, but share a URL that is too long is very annoying thing. There for Shortened URL Plays a crucial role.
So In this article we learn how to build a URL Shortener Application in flutter.

How to user flutter URL Shortener

Our Flutter URL Shortener Application we have 3 pages.

  1. Registration.
  2. Login.
  3. Dashboard.

In Registration Page we simply have a form that the user can fill to register himself into our application using Flutter registration page.

In Login page user can enter his login credential and get logged in into the flutter to make use of URL Shortener.

In Dashboard we have 2 section. First section user can use to submit his LongURL and get ShortURL. Second section we can show all the data i.e. short URL created by that user.


Libraries need to created URL Shorten project in flutter

In pubspec.yaml file under dependencies we need to add below 2 library.

  get:
  get_storage:

We are going to make use of getx and get storage package

getx: used to make http calls to back api to store and retrieve data from backend nodejs server.

get storage: used to share logged in user data within the application storage same like sharedPreference.

Flutter URL Shortener Project Structure

url shortener flutter

In above flutter project I have 4 dart files namely:

  1. main.dart
  2. registration.dart
  3. login.dart
  4. dashboard.dart

main.dart

This is the starting point of our flutter application, Here we will check if the user has already signed into the application before, If the user data exist in get_storage (shared preferences) we will redirect the user to dashboard page else will redirect user to login page.

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:url_shortener/dashboard.dart';
import 'package:url_shortener/login.dart';
import 'package:get_storage/get_storage.dart';
void main() async{
  await GetStorage.init();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  final get_storage = GetStorage();
  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    get_storage.writeIfNull('user', false);

    Future.delayed(Duration(seconds: 2),() async{

      print(get_storage.read('user'));
       checkUserData();
    });


  }

  checkUserData(){
    if(get_storage.read('user').toString().isNotEmpty || get_storage.read('user') ){
      Navigator.push(context, MaterialPageRoute(builder: (builder)=>Dashboard()));
    }else{
      Navigator.push(context, MaterialPageRoute(builder: (builder)=>Login()));
    }
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: CircularProgressIndicator(),
      ),
    );
  }
}

login.dart

In login page we have 2 text field where the user can enter login credential i.e. email & password and a button on click will call a function that hit back-end NodeJS Login API.

After hitting the backEnd API if user exist in our MongoDB database will send the user data as response to frontEnd, and then store the user data into flutter app storage space using GetStorage package so that the used will be signIn into the application when he visit next time.

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:url_shortener/dashboard.dart';
import 'package:url_shortener/registration.dart';
import 'package:get_storage/get_storage.dart';

class Login extends StatefulWidget {
  const Login({super.key});

  @override
  State<Login> createState() => _LoginState();
}

class _LoginState extends State<Login> {

  TextEditingController emailText = TextEditingController();
  TextEditingController passText = TextEditingController();
  final getConnect = GetConnect();
  final get_storage = GetStorage();

  void _login(email,pass) async{

    if(email.isEmpty || pass.isEmpty){
      Get.snackbar("Please Enter Email And Password", '');
    }else{
      final res = await getConnect.post('http://192.168.29.239:3000/userLogin', {
        "email":email,
        "password":pass

      });

      if(res.body['status']){
        get_storage.write('user', res.body['success']);
        Navigator.push(context, MaterialPageRoute(builder: (builder)=>Dashboard()));
      }else{
        Get.snackbar(res.body['success'], '');
      }
    }

  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: SingleChildScrollView(
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                SizedBox(height: 10,),
                const Text("* URL SHORTENER *",style: TextStyle(fontSize: 30),),
                const Text("Login Page"),
                SizedBox(height: 10,),
                Padding(
                  padding: const EdgeInsets.fromLTRB(25, 20, 25, 2),
                  child: TextField(
                    controller: emailText,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                        filled: true,
                        fillColor: Colors.white,
                        hintText: "Email",
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.all(Radius.circular(10.0)))),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(25, 20, 25, 2),
                  child: TextField(
                    controller: passText,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                        filled: true,
                        fillColor: Colors.white,
                        hintText: "Password",
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.all(Radius.circular(10.0)))),
                  ),
                ),

                ElevatedButton(
                  onPressed: () {
                      _login(emailText.text,passText.text);
                  },
                  child: Text("LOGIN"),
                ),

                Padding(padding: EdgeInsets.all(20),child:
                ElevatedButton(
                  onPressed: () {
                    Navigator.push(context, MaterialPageRoute(builder: (builder)=>Registration()));
                  },
                  child: Text("REGISTER"),
                ),),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
url shortener login page

registration.dart

Using this page user can register himself into the system.

Here we accept 3 data from the user i.e. Name, Email and Password using Text Fields.

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:url_shortener/login.dart';


class Registration extends StatefulWidget {
  const Registration({super.key});

  @override
  State<Registration> createState() => _RegistrationState();
}

class _RegistrationState extends State<Registration> {

  TextEditingController nameText = TextEditingController();
  TextEditingController emailText = TextEditingController();
  TextEditingController passText = TextEditingController();
  final getConnect = GetConnect();


  void _register(name,email,pass) async{
    print("${name},${email},${pass}");

    if(name.isEmpty || email.isEmpty || pass.isEmpty){
      Get.snackbar("Please Enter Details", '');
    }else{
      final res = await getConnect.post('http://192.168.29.239:3000/userRegistration', {
        "name":name,
        "email":email,
        "password":pass
      });

      if(res.body['status']){
        Navigator.push(context, MaterialPageRoute(builder: (builder)=>Login()));
      }else{
        Get.snackbar(res.body['success'], 'message');
      }
    }

  }
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: SingleChildScrollView(
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                SizedBox(height: 10,),
                const Text("* URL SHORTENER *",style: TextStyle(fontSize: 30),),
                const Text("Registration Page"),
                SizedBox(height: 10,),
                Padding(
                  padding: const EdgeInsets.fromLTRB(25, 10, 25, 2),
                  child: TextField(
                    controller: nameText,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                        filled: true,
                        fillColor: Colors.white,
                        hintText: "Full Name",
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.all(Radius.circular(10.0)))),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(25, 20, 25, 2),
                  child: TextField(
                    controller: emailText,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                        filled: true,
                        fillColor: Colors.white,
                        hintText: "Email",
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.all(Radius.circular(10.0)))),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(25, 20, 25, 2),
                  child: TextField(
                    controller: passText,
                    keyboardType: TextInputType.text,
                    decoration: InputDecoration(
                        filled: true,
                        fillColor: Colors.white,
                        hintText: "Password",
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.all(Radius.circular(10.0)))),
                  ),
                ),
                Padding(padding: EdgeInsets.all(20),child:
                ElevatedButton(
                  onPressed: () {
                      _register(nameText.text,emailText.text,passText.text);
                  },
                  child: Text("REGISTER"),
                ),),
                ElevatedButton(
                  onPressed: () {
                    Navigator.push(context, MaterialPageRoute(builder: (builder)=>Login()));
                  },
                  child: Text("LOGIN"),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
url shortener registration page

dashboard.dart

This Page and 2 section

  • First section user can use to submit his LongURL and get ShortURL.
  • Second section we can show all the data i.e. short URL created by that user.
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';

class Dashboard extends StatefulWidget {
  const Dashboard({super.key});

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

class _DashboardState extends State<Dashboard> {
  final getStoage = GetStorage();
  final textLongUrl = TextEditingController();
  final getConnect = GetConnect();

  List<Map<String,dynamic>> dataList = [];

  void _urlSubmit(longurl) async{

    Map<String,dynamic> userData = getStoage.read('user');
    String userId = userData['_id'];

    final res = await getConnect.post('http://192.168.29.239:3000/urlSubmit',
        {
          'userId': userId,
          'longUrl': longurl
    });

    print(res.body['shortUrl']);

    Get.snackbar("Short URL Created", res.body['shortUrl']);
    textLongUrl.text="";
  }

  Future<void> _fetchUserUrl(userId) async {
  
    final response = await getConnect.post('http://192.168.29.239:3000/getUserURL', {
        'userId' : userId
    });

    final List<dynamic> data = response.body['success'];

    setState(() {
      dataList = List<Map<String,dynamic>>.from(data);
    });
    
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    Map<String,dynamic> userData = getStoage.read('user');
    String userId = userData['_id'];

    _fetchUserUrl(userId);

  }

  @override
  Widget build(BuildContext context) {
    return  Scaffold(
      body: SafeArea(
        child: SingleChildScrollView(
          child: Center(
            child: Container(
              height: MediaQuery.of(context).size.height,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  SizedBox(height: 10,),
                  const Text("* URL SHORTENER *",style: TextStyle(fontSize: 30),),
                  const Text("Long URL to Short URL"),
                  SizedBox(height: 10,),
                  Padding(
                    padding: const EdgeInsets.all(16.0),
                    child: Form(
                      child: Row(
                        children: [
                          Expanded(
                            child: TextFormField(
                                decoration: InputDecoration(
                                  filled: true,
                                  fillColor: Colors.white,
                                  hintText: "Long URL",
                                  border: OutlineInputBorder(
                                      borderRadius: BorderRadius.all(Radius.circular(10.0))
                                  ),
                                ),
                                controller: textLongUrl,
                                validator: (value){
                                  if(value == null || value.isEmpty){
                                    return " Please Enter long Url";
                                  }
                                  return null;
                                }
                            ),
                          ),
                          SizedBox(width: 10), // Add some spacing between TextField and Button
                          ElevatedButton(
                            onPressed: () {
                              _urlSubmit(textLongUrl.text);
                            },
                            child: Text('Submit'),
                          ),
                        ],
                      ),
                    ),
                  ),
                  dataList.isEmpty ? CircularProgressIndicator(): Expanded(
                    child: Container(
                      child: ListView.builder(
                        itemCount: dataList.length,
                          itemBuilder: (context,index){
                          return Card(
                            elevation: 2,
                            margin: EdgeInsets.symmetric(vertical: 6,horizontal: 16),
                            child: ListTile(
                              title: Text("http://192.168.29.239/${dataList[index]['shorturl']}"),
                              subtitle: Text('${dataList[index]['longUrl']}'),
                            ),
                          );
                          }
                      ),
                    ),
                  )
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}
url shortener dashboard page

Video Tutorial on building URL Shortener Project

Below is playlist of my YouTube tutorial on building URL Shortener Application using Flutter for frontend and NodeJS with MongoDB at backend.


URL Shortener BackEnd complete source code

Building a URL Shortener Project with Node.js – Backend

0
nodejs url shortener project
nodejs url shortener project

Introduction

In the world of web application development, building a URL shortener server is best for beginners who wants to learn for scratch and also best for collage student who want to submit a project. A URL shortener project takes long URLs and provides a shortened link, making links more manageable and shareable in short form links. In this article, we will help you in developing a nodejs application in building a URL shortener using Node.js, Express, and MongoDB.

Video Playlist on building URL Shortener in Flutter + NodeJS with MongoDB Database

Project Structure

nodejs url shortener

The NodeJS project will be organized into folders such as config, model, and routers for better code structure.

  1. config: In config folder we have a file db.js that is responsible for mongodb database connectivity.
  2. model: In model folder we have files that define mongodb database schema, Here we have 2 file namely url.model.js and user.model.js.
  3. routers: In router folder we have RESTAPI for url and user apis.
  4. app.js and index.js: This main root / starting point of our nodejs express URL shortener application in nodejs.

Node Module / Libraries required for building URL shortener Application

  1. body-parser: used for parse incoming request bodies from client or front-end.
  2. cors: Enables secure cross-origin resource sharing.
  3. express: used to simplify the creation of nodejs express server and creating API and routers.
  4. mongoose: used to connect or interact with MongoDB database, creating mongodb collection schema.
  5. shortid: used for generating unique random identifier, that we can used as shortURL.

Enter below command to install this nodeJS Modules or Libraries

npm install body-parser cors express mongoose shortid

URL Shortener in NodeJS using ExpressJS and MongoDB

Refer above project structure and create respective files under the folders.

config > db.js

This file is responsible to get connected to mongodb database using nodejs mongoose library.
This connection is exported so that the connection can we used in model file as below.

const mongoose = require('mongoose');

const connection = mongoose.createConnection('mongodb://127.0.0.1:27017/url_shortener')

connection.on('connected',()=>{
    console.log("DB Connected");
})


module.exports = connection;

modul > url.model.js

This is a MongoDB schema for url collection, where we are going to store user submitted URL’s data like userId, longUrl and shorturl.

const mongoose = require('mongoose');
const db = require('../config/db');
const userModel = require('./user.model')

const { Schema } = mongoose;

const urlSubmitionSchema = new Schema({
    userId:{
        type: Schema.Types.ObjectId,
        ref: userModel.modelName
    },
    longUrl:{
        type : String
    },
    shorturl:{
        type : String
    }
});

const urlSubmitionModel = db.model('urlSubmittion',urlSubmitionSchema);
module.exports = urlSubmitionModel;

modul > user.model.js

This is a MongoDB schema for user collection, where we are going to store users data like name, email and password.

const mongoose = require('mongoose');
const db = require('../config/db');

const { Schema } = mongoose;

const userSchema = new Schema({
    name:{
        type:String
    },
    email:{
        type:String
    },
    password:{
        type:String
    },
})

const userModel = db.model('users',userSchema);
module.exports = userModel;

routers > url.router.js

This use url routers has 3 API:

  1. urlSubmit: Using this we can convert long URL into shorturl, Basically this API is used for LongURL submition and get shortURL of it.
    This API accept 2 parameters: userId & longUrl then generate a shortId i.e a random id which we can use as shortURL. This whole data will be stored into Mongodb database.
  2. /:url: this api is a parameterized API, for example support a longURL is submitted and uses get the shortURL it, Now the user can us url like this http://localhost:3000/xya12id to redirect himself to longURL.
  3. getUserURLList: This API will return all the URL’s been submitted by the user, This is been used to show or display the list of URL in Frontend (URL Shortener Flutter App).
const router = require('express').Router();
const shortId = require('shortid');
const urlSubmitModel = require("../model/url.model");

router.post('/urlSubmit', async (req, res) => {
    const { userId, longUrl } = req.body;
    try {
        const randonurl = shortId.generate();
        const urlSubmit = new urlSubmitModel({ userId, longUrl, shorturl: randonurl });
        await urlSubmit.save();

        res.json({ status: true, shortUrl: `http://localhost:3000/${randonurl}` })
    } catch (error) {
        res.json({ status: false, message: "Something went wrong" })
    }
});

router.get('/:url',async(req,res)=>{
   const {url} = req.params;

   const urldata = await urlSubmitModel.findOne({shorturl:url})

   console.log(urldata);

   if(urldata){
            res.redirect(urldata.longUrl);
   }else{
    res.json({status:false,message:"invalid url"})
   }

});

router.post('/getUserURLList',async(req,res)=>{
    const {userId} = req.body;
    const allUserUrl = await urlSubmitModel.find({userId});
    if(allUserUrl){
        res.json({status:true,success:allUserUrl})
    }else{
        res.json({status:false,message:"no data found"});
    }
})



module.exports = router;

routers > user.routers.js

In user API routers we will have 2 API for users

  1. userRegistration: using this we can register user to our system.
  2. userLogin: Using this the user can use his credential or login detail to Login into our URL Shortener Flutter Application.
const router = require('express').Router();
const userModel = require('../model/user.model');


router.post('/userRegistration', async (req,res)=>{
    try {
        const {name,email,password} = req.body;

        const user = await userModel.findOne({email});
        if(!user){
            const createuser = new userModel({name,email,password});
            await createuser.save();


            res.json({status:true,success : "User Created Successfully"});
        }else{
            res.json({status:false,success : "User Exist"});
        }

    } catch (error) {
        console.log(error);
    }
   

});



router.post('/userLogin', async (req,res)=>{
    try {
        const {email,password} = req.body;

        const user = await userModel.findOne({email,password});
        if(user){
           
            res.json({status:true,success : user});
        }else{
            res.json({status:false,success : "User Invalid Please Try Again"});
        }

    } catch (error) {
        console.log(error);
    }
});

module.exports = router;


app.js

The app.js file is where we will define our middleware like cors, routers using express, and is exported using module.exports and imported in index.js

const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const userRouter = require('./routers/user.router');
const urlRouter = require('./routers/url.router');
const app = express();

app.use(cors());

app.use(bodyParser.json({limit:'50Mb'}));
app.use(bodyParser.urlencoded({limit:'50Mb',extended:true}))

app.use('/',userRouter);
app.use('/',urlRouter);

module.exports = app;

index.js

This file is where our NodeJS Express Server start.

const app = require("./app")


app.get('/',(req,res)=>{
    const { data } = req.body;
   res.send(` Hello ${data}`)
})

app.listen(3000,()=>{
    console.log("Localhost Express running at 3000");
})

How to run url shortener backend nodejs server

node index.js

Flutter URL Shortener Complete Source Code