Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to send a request after the user has stopped typing?

  • I am looking for a way to send an API request after the user has stopped typing for X amount of seconds.
  • The way I am sending the request is through the onTextChanged callback, however, that sends a request on every key press
  • I have seen ways to do this with a timeout in React, however, I am relatively new to flutter so any help would be appreciated
like image 935
vox Avatar asked Nov 04 '18 22:11

vox


People also ask

How do you execute a function only after the user stops typing?

Solution. To avoid that problem, we better execute a function in proper timing which means after a user stops typing for a while. And setTimeout helps us to do that. The setTimeout() method calls a function or evaluates an expression after a specified number of milliseconds.

How we can call function when user ended typing in input?

step 1. set time out to null then clear the current timeout when the user is typing. step 2. trigger clear timeout to the variable define before keyup event is triggered.

How do you trigger an event in input text after quitting typing writing?

$('input#username'). keypress(function() { var _this = $(this); // copy of this object for further usage setTimeout(function() { $. post('/ajax/fetch', { type: 'username', value: _this. val() }, function(data) { if(!


2 Answers

you can use the below code to do this:

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

class Test extends StatefulWidget {
    @override
    State<StatefulWidget> createState() {
        return _TestState();
    }
}

class _TestState extends State<StatefulWidget> {
    Timer searchOnStoppedTyping;

    _onChangeHandler(value ) {
        const duration = Duration(milliseconds:800); // set the duration that you want call search() after that.
        if (searchOnStoppedTyping != null) {
            setState(() => searchOnStoppedTyping.cancel()); // clear timer
        }
        setState(() => searchOnStoppedTyping = new Timer(duration, () => search(value)));
    }

    search(value) {
        print('hello world from search . the value is $value');
    }
    @override
    Widget build(BuildContext context) {
        return TextField(
            onChanged: _onChangeHandler,
            decoration: InputDecoration(
                hintText: 'Search ....'
                ),
            );
    }
}
like image 124
Mahdi Tohidloo Avatar answered Oct 26 '22 15:10

Mahdi Tohidloo


The usual way to do this in Flutter is using RxDart and its debounce() method. It allows to wait a small period before launching a specific call.

In the following full example you see it in action with a time of 1 second. In the example, a message is shown where the call to the server should be dispatched.

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

void main() => runApp(new MyApp());

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final subject = new PublishSubject<String>();

  bool isLoading = false;

  GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey();

  void _textChanged(String text) {
    if (text.isEmpty) {
      setState(() {
        isLoading = false;
      });
      return;
    }
    setState(() {
      isLoading = true;
    });
    scaffoldKey.currentState.showSnackBar(new SnackBar(
      content: new Text("Search for ${text}"),
    ));
  }

  @override
  void initState() {
    super.initState();
    subject.stream.debounce(new Duration(milliseconds: 1000)).listen(_textChanged);
  }

  @override
  void dispose() {
    subject.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      key: scaffoldKey,
      appBar: new AppBar(
        title: new Text("Debounce demo"),
      ),
      body: new Container(
        padding: new EdgeInsets.all(8.0),
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            new TextField(
              decoration: new InputDecoration(
                hintText: 'Type text to search',
              ),
              onChanged: (string) => (subject.add(string)),
            ),
            isLoading
                ? Padding(
                    padding: const EdgeInsets.all(20.0),
                    child: new CircularProgressIndicator(),
                  )
                : new Container(),
          ],
        ),
      ),
    );
  }
}

You can see this code in action in the following article and code by Norbert Kozsir

like image 30
chemamolins Avatar answered Oct 26 '22 13:10

chemamolins