Angular 5 (ionic 3) does not support the FormControl debounceTime feature

Recently, I upgraded Angular in my Ionic app from version 4 to 5. In the app, I have search FormControl inputs that allow users to search a database through ajax requests. Previously, I used the debounceTime() method to delay the ajax search request. However, after the Angular upgrade, this method is no longer available. As a result, every key press by the user on Android now triggers a new request.

Is there an alternative way to implement this delay?

this.searchControl.valueChanges
        .debounceTime(2000)
        .subscribe(search => this.getCities(search));

Answer №1

In the Ionic documentation, it is highlighted that:

RXJS 5.5.2 Updates

The most recent RXJS update involves a change in how operators are applied.

Previously, operators were implemented like this:

import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/switchMap';

export MyClass {

  someMethod(){
    // Using Reactive Forms
    this.input.valueChanges
    .debounceTime(500)
    .switchMap(inputVal => this.service.get(inputVal))
    .subscribe(res => console.log(res))
  }
}

This method required modifying the Observable prototype and patching on the methods.

With the release of RXJS 5.5, a new approach using lettable operators has been introduced, which can result in significantly smaller code bundles.

To utilize lettable operators, the previous code needs to be adjusted as follows:

// Use Deep imports here for smallest bunlde size
import { debounceTime } from 'rxjs/operators/debounceTime';
import { switch } from 'rxjs/operators/switchMap'; // <- Please read the update!

export MyClass {

  someMethod(){
    // Using Reactive Forms
    // We use the new `.pipe` method on the observable
    // too apply operators now

    this.input.valueChanges
    .pipe(
      debounceTime(500),
      switchMap(inputVal => this.service.get(inputVal))
    )
    .subscribe(res => console.log(res))
  }
}

This minor adjustment allows importing only the necessary operators in our code, resulting in a smaller, faster application. This example demonstrates the use of Deep Imports, enabling isolation of the imported module.

Therefore, by slightly altering the import statement to incorporate deep imports:

import { debounceTime } from 'rxjs/operators/debounceTime';

And then utilizing debounceTime within the pipe(...) method:

this.input.valueChanges
    .pipe(
      debounceTime(500),
      // additional operators can be chained if needed ...
      // ...
    )
    .subscribe(res => console.log(res))

Although the old method can still be used (as it's not yet a breaking change), switching to lettable operators will optimize the application, making it smaller and faster.


UPDATE

As pointed out by @lifetimes in their comment (and corroborated here), the import statement:

import { switch } from 'rxjs/operators/switchMap';

should be replaced with:

import { switchMap } from 'rxjs/operators/switchMap';

when working with newer versions.

Answer №2

Perhaps you will find this example helpful:

const debounceValue = this.name.valueChanges.pipe(
  debounceTime(1000), // delaying by 1000 milliseconds
  distinctUntilChanged() // filtering out unchanged values
);
debounceValue.subscribe(value => {
  console.log(value);
});

Answer №3

In the upcoming version of Rxjs (which will be used in Angular 5), there have been alterations to the syntax for utilizing Rxjs operators. Give this a try:

this.searchControl.valueChanges
    .pipe(debounceTime(2000))
    .subscribe(search => this.getCities(search));

If needed, ensure to import pipe and debounceTime.

Answer №4

(12th April 2019) It's important to note that there have been recent updates to the code provided in these answers. As of now, debounce now requires a

durationSelector: (value T) => SubscribableOrPromse<any>
. Therefore, the revised solution is as follows:

this.searchControl.valueChanges
    .pipe(debounceTime(() => interval(2000)))
    .subscribe(search => this.getCities(search));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What could be the possible reason for the token having a null value during login authentication in

As a beginner to Angular, I am facing an issue with my JWT login page implementation. Despite printing the token in the console and confirming its existence as a string, I am receiving a null (or undefined) value. This is the code snippet from my UserServi ...

Error: NgFor can only be used to bind to data structures that are iterable, such as Arrays. JSON arrays are

Encountering ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables like Arrays. *ngFor="let spec of vehicleSpecs" Tried various solutions and searched extensi ...

Intellisense for dispatch types in Redux Toolkit

After following the documentation for redux toolkit with typescript, I implemented my own useDispatch hook as shown below export const useAppDispatch = () => useDispatch<AppDispatch>() and used it in components like this const dispatch = useAppDi ...

Unable to load the node modules

In my development journey, I created an ASP.NET MVC project using Angular 2 in Visual Studio 2017 and set up node for package management. Here is a snippet from the package.json file: { "version": "1.0.0", "name": "asp.net", "private": true, ... ...

An HTTP request is made with a JSON parameter to invoke a server-side GET function that does not

Having an issue with Angular's get method and unsure why the second server side function is being called instead of the first. Here is my code: var params = { "id": templateCategoryId }; this.http.get(this.appService.baseUrl + 'api/UserL ...

Is there a more efficient method to tally specific elements in a sparse array?

Review the TypeScript code snippet below: const myArray: Array<string> = new Array(); myArray[5] = 'hello'; myArray[7] = 'world'; const len = myArray.length; let totalLen = 0; myArray.forEach( arr => totalLen++); console.log(& ...

What steps can I take to avoid encountering the `@typescript-eslint/unbound-method` error while utilizing the `useFormikContent()` function?

Recently, I updated some of the @typescript-eslint modules to their latest versions: "@typescript-eslint/eslint-plugin": "3.4.0", "@typescript-eslint/parser": "3.4.0", After the update, I started encountering the fo ...

Is there a way to access the value of a public variable within the @input decorator of a function type?

I am working on a dropdown component that utilizes the @Input decorator to define a function with arguments, returning a boolean value. dropdown-abstract.component.ts @Input() public itemDisabled: (itemArgs: { dataItem: any; index: number }) => boo ...

Tips for avoiding simultaneous state transitions in Angular UI Router

My situation in my Angular application involves a frustrating issue. Whenever a user double-clicks quickly on a link to a specific state (ui-sref link), the target state starts loading twice. This would be manageable if the state window didn't freeze ...

Utilizing a Map with Angular's ngFor

Currently, I am working with Ionic 3, which utilizes Angular and TypeScript. My goal is to use ngFor with a Map type in my project. Below is what I have implemented so far: interface IShared_Position { lat: number; lng: number; time: number; ...

The variable "randomString" has not been declared within the HTMLInputElement.onclick function in Types

I need a function that can generate a random string or number for me. Initially, my function in TypeScript looked like this: randomString() { let chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; let string_length = 8; ...

VS Code sees JavaScript files as if they were Typescript

I have recently delved into the world of Typescript and have been using it for a few days now. Everything seems to be working smoothly - Emmet, linting, etc. However, I've encountered an issue when trying to open my older JavaScript projects in VS Cod ...

What is the best way to retrieve and showcase data in NextJs version 13 and beyond?

Being new to NextJS, my question may seem trivial but I'd appreciate your patience. Essentially, my goal is to fetch data from a database and display it on the page upon the initial render. To achieve this, I am utilizing the useEffect and useState ho ...

Issue with importing Typescript and Jquery - $ function not recognized

Currently, I am utilizing TypeScript along with jQuery in my project, however, I keep encountering the following error: Uncaught TypeError: $ is not a function Has anyone come across this issue before? The process involves compiling TypeScript to ES20 ...

Implementing a click event to convert text to input in Angular 5

I'm struggling with setting values instead of just getting them. I want to switch from using divs to input fields and update the values when in "editMode". <div class="geim__sets"> <div *ngFor="let set of game.sets" class="geim__set"> ...

The container struggles to contain the excess of images spilling over

I'm having trouble getting a group of images to stay within their container in a grid layout, as they're overflowing vertically beyond the container's boundaries. Is there a way to adjust their size so they match the height of their parent ...

The displayed number of rows in the paginator selection is inaccurate

My table in Angular Material is displaying the 'Items per page' numbers under the table instead of under the select option element (orange marker). Can someone explain why this is happening? Here is my HTML template: <div class="containe ...

Creating a variable that is not defined and then converting it into

I have an issue with a function that returns an Observable. The problem is that when the function is called, the parameter works fine, but its value becomes undefined within the Observable. This is the function in question: import {Observable} from &apos ...

Make sure to wait for a Promise to resolve before initiating another Promise within a for loop in Angular

Issue: I am trying to call multiple APIs in sequence within a for loop and need each API call to wait for the previous one to resolve before making the next call. Within my code, I have a for loop that calls a Get API to generate documents on the server s ...

The Maven build encountered an error while trying to execute a goal, resulting in the inability to

I'm currently working on a Windows 7 computer and I've received some code that requires me to execute "mvn install" in order to build the application. However, when I try to run this command, I encounter the following error: Failed to execute ...