flutter debouncing
flutter debouncing

Hi Guys, Welcome to Proto Coders Point This flutter article is on what is debouncing & how to implement it in flutter.

What is Debouncing?

Debouncing is a effective way to implement searching functionality. Basically Debouncing is a technique by which we can control and manage user input by preventing unnecessary hits to server API.

When is debouncing used?

Debouncing is usually used in search fields, such as when a user type a letter in a textField, A API is called and then a fetched results from API is displayed.

Just consider that you are calling a API when there is a key pressed (user types a letters) onChanged method is used in Flutter TextField, Let’s assume that a user types a word dog in the search field, Here for each letter typed by user onChanged() method makes a call to API means 3 times API is called, which is not a right way to implement search field. This creates a rapid and unnecessary operation like network api call request or state updates. To prevent this we make use of Deboucing in flutter.

Debouncing was build to create a delay before performing request event for user input. There a a delay in user typing a letter, So when a user continuously types word “dog” and then keep a gap of 500 milliseconds, Now the API is triggered making it a more effective way to implement searching field in flutter.

How to implement debouncing in flutter?

Here are steps to implement debounce in flutter.

First let create a Timer() object will name it as _debounceTimer.

Timer? _debounceTimer;

Then in TextField we have a method onChanged() a listener that listens to each key/letter press or cleared by user in textField

TextField(
          controller: _controller,
          onChanged: (text) {
               print('Making API Call for Text: $text (${text.characters.length})');
          },
          decoration: InputDecoration(labelText: 'Enter text'),
        ),

In above code onChanged() method listens to each letter types in textField, That makes a call to a API on eack key press. To prevent this will make use of debouncing technique that is simple keeping a time gap before making a call to the server API.

TextField(
          controller: _controller,
          onChanged: (text) {
              if (_debounceTimer != null) {
                  _debounceTimer!.cancel();
              }

           _debounceTimer = Timer(Duration(milliseconds: 500), () {
                    // Perform your desired action here, e.g., make an API request.
                    print('Performing action with text: $value');
              });
          },
          decoration: InputDecoration(labelText: 'Enter text'),
  ),

In above example, Then a user types letters in textField rapidly the timer object reset itself so the API call is not made, and if the user keep a gap of 500 millisecond period within his typing speed then API call is made like searching a list of data that started with letter typed by user in textField.


Complete code – debouncing in flutter

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DebounceExample(),
    );
  }
}

class DebounceExample extends StatefulWidget {
  @override
  _DebounceExampleState createState() => _DebounceExampleState();
}

class _DebounceExampleState extends State<DebounceExample> {
  final TextEditingController _controller = TextEditingController();
  Timer? _debounceTimer;

  @override
  void dispose() {
    _controller.dispose();
    _debounceTimer?.cancel();
    super.dispose();
  }

  void _onTextChanged(String value) {
    // Debounce the text input by delaying the action for 500 milliseconds.
    if (_debounceTimer != null) {
      _debounceTimer!.cancel();
    }

    _debounceTimer = Timer(Duration(milliseconds: 500), () {
      // Perform your desired action here, e.g., make an API request.
      print('Performing action with text: $value');
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Debounce Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: TextField(
          controller: _controller,
          onChanged: _onTextChanged,
          decoration: InputDecoration(labelText: 'Enter text'),
        ),
      ),
    );
  }
}