319

When I run the linter it says:

subscribe is deprecated: Use an observer instead of an error callback

Code from this angular app:

    this.userService.updateUser(data).pipe(
       tap(() => {bla bla bla})
    ).subscribe(
       this.handleUpdateResponse.bind(this),
       this.handleError.bind(this)
    );

Don't know exactly what should I use and how...

Thanks!

ismaestro
  • 7,561
  • 8
  • 37
  • 50

10 Answers10

452

subscribe isn't deprecated, only the variant you're using is deprecated. In the future, subscribe will only take one argument: either the next handler (a function) or an observer object.

So in your case you should use:

.subscribe({
   next: this.handleUpdateResponse.bind(this),
   error: this.handleError.bind(this)
});

See these GitHub issues:

Christian Jensen
  • 900
  • 1
  • 10
  • 25
martin
  • 93,354
  • 25
  • 191
  • 226
  • 57
    idk... hovering in vs code still shows deprecated with that syntax (rxjs 6.5.3) – Yannic Hamann Nov 19 '19 at 15:10
  • 21
    Hey @YannicHamann [this comment](https://github.com/ReactiveX/rxjs/issues/4159#issuecomment-466630791) explains why. It's not deprecated, they just deprecated one of the overloads and now it looks like everything is deprecated. It's a tooling issue mostly. – Dean Feb 09 '20 at 23:32
  • 5
    I think this answer is not anymore valid since all subscribe methods are deprecated now in rxjs 6.5.4 – Alok Rajasukumaran Jun 21 '20 at 18:42
  • 5
    It there a migration script that will automatically update all our `subscribe()` methods? We have hundreds of them in our project, I can't imagine having to do this manually! – AsGoodAsItGets Mar 05 '21 at 11:13
  • 5
    @AlokRajasukumaran how are we suposed subscribe nowadays? – Leonardo Rick Mar 06 '21 at 16:51
  • We actually went to a normal method without rxjs for the same. – Alok Rajasukumaran Mar 08 '21 at 07:02
  • 2
    @AlokRajasukumaran *Not* all methods are deprecated now. It's just that certain tools misinterpret the source and think all are deprecated. (see: [Code on github](https://github.com/ReactiveX/rxjs/blob/5e95503828798326947fc1dc1b98f69e9e04058c/src/internal/Observable.ts#L71)) – JackDMF Mar 09 '21 at 12:11
  • 1
    Hmm, weird. The deprecated warning does not disappear after fix. – Domske Mar 16 '21 at 12:31
  • 1
    I'm using the preferred syntax in all my components and still getting the deprecation message. – Darren Street Mar 18 '21 at 10:55
156

Maybe interesting to note that the observer Object can also (still) contain the complete() method and other, additional properties. Example:

.subscribe({
    complete: () => { ... }, // completeHandler
    error: () => { ... },    // errorHandler 
    next: () => { ... },     // nextHandler
    someOtherProperty: 42
});

This way it is much easier to omit certain methods. With the old signature it was necessary to supply undefined and stick to the order of arguments. Now it's much clearer when for instance only supplying a next and complete handler.

magikMaker
  • 4,929
  • 1
  • 33
  • 25
  • How to access `real this`, if using this form? – Sebi2020 Jan 09 '22 at 16:05
  • 1
    Not sure what you mean with `real this`. It's always possible to use a variable, something like `let scopedThis = this` or you can you `bind()` for instance. – magikMaker Jan 10 '22 at 17:57
  • Exactly what I was looking for! When passing an `observer` object into `subscribe()` there is no need to explicitly type `undefined` as a missing argument when you don't want to specify `next()` or `error()` callbacks. – Theta Jun 24 '22 at 16:33
55

For me, it was just the typescript version my VSCode was pointing to.

VSCode status bar

TypeScript version selector

Select local TypeScript version

Got help from this GitHub comment.

I believe this is a typescript issue. Something in the newest versions of typescript is causing this warning to display in vs code. I was able to get it to go away by click the version of typescript in the bottom right corner of vs code and then choosing the select typescript version option. I set it to the node_modules version we have installed in our angular project which in our case happens to be 4.0.7. This caused the warnings to go away.

Paritosh
  • 11,144
  • 5
  • 56
  • 74
30

Find the details at official website https://rxjs.dev/deprecations/subscribe-arguments

Notice the {} braces in second subscribe code below.

import { of } from 'rxjs';

// recommended 
of([1,2,3]).subscribe((v) => console.info(v));
// also recommended
of([1,2,3]).subscribe({
    next: (v) => console.log(v),
    error: (e) => console.error(e),
    complete: () => console.info('complete') 
})
ouflak
  • 2,458
  • 10
  • 44
  • 49
Gautam Pandey
  • 301
  • 3
  • 5
23

You can get this error if you have an object typed as Observable<T> | Observable<T2> - as opposed to Observable<T|T2>.

For example:

    const obs = (new Date().getTime() % 2 == 0) ? of(123) : of('ABC');

The compiler does not make obs of type Observable<number | string>.

It may surprise you that the following will give you the error Use an observer instead of a complete callback and Expected 2-3 arguments, but got 1.

obs.subscribe(value => {

});

It's because it can be one of two different types and the compiler isn't smart enough to reconcile them.

You need to change your code to return Observable<number | string> instead of Observable<number> | Observable<string>. The subtleties of this will vary depending upon what you're doing.

Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
14

The new Way of using RxJS is quit simple:

previous versions:

this.activatedRoute.queryParams.subscribe(queryParams => {
console.log("queryParams, queryParams)

}, error => {
})

New Version:

  this.activatedRoute.queryParams.subscribe(
  {
    next: (queryParams) => {
      console.log('queryParams', queryParams);
    },

    error: (err: any) => { },
    complete: () => { }
  }
);
Vikram Kumar
  • 397
  • 3
  • 2
4

I migrated my Angular project from TSLint to ESLint and it is now not showing the warning anymore!

I followed these steps. (End of each step I also recommend to commit the changes)

  1. Add eslint: ng add @angular-eslint/schematics

  2. Convert tslint to eslint: ng g @angular-eslint/schematics:convert-tslint-to-eslint

  3. Remove tslint and codelyzer: npm uninstall -S tslint codelyzer

  4. If you like to auto fix many of the Lint issues ng lint --fix (It will also list the not fixed issues)

  5. In VSCode uninstall the TSLint plugin, install ESLint plugin and Reload the VSCode.

  6. Make sure it updated the package and package-lock files. Also the node_modules in your project.

  7. If you have the tsconfig.json files under sub directory - you need to add/update the projects-root-directory/.vscode/settings.json with the sub directory where the tsconfig files are!

    {
      "eslint.workingDirectories": [
        "sub-directory-where-tsconfig-files-are"
      ]
    }
    
Lahar Shah
  • 7,032
  • 4
  • 31
  • 39
  • 1
    More details here, about migration from TSLint to ESNint, in VS Code official page: https://code.visualstudio.com/api/advanced-topics/tslint-eslint-migration – viking Feb 10 '22 at 14:24
2

I was getting the warning because I was passing this to subscribe:

myObs.subscribe(() => someFunction());

Since it returns a single value, it was incompatible with subscribe's function signature.

Switching to this made the warning go away (returns null/void);

myObs.subscribe(() => {
  someFunction();
});
inorganik
  • 24,255
  • 17
  • 90
  • 114
1

You should replace tslint with eslint.

As TSLint is being deprecated it does not support the @deprecated syntax of RXJS. ESLint is the correct linter to use, to do subscribe linting correctly.

LessQuesar
  • 3,123
  • 1
  • 21
  • 29
  • 11
    I don't think this solution is good, because ignoring a problem doesn't solve it. – Remy Apr 06 '21 at 10:14
  • 3
    In this case it's not a matter of ignoring the problem because seems to be only a TSLint bug: https://stackoverflow.com/a/66605060/2445651 ... but more important to know is that TSLint has been deprecated in favour of ESLint: https://stackoverflow.com/a/66933996/2445651 – Rancid Apr 29 '21 at 11:18
  • It's not ignoring, it removes a false error. – Caveman Jul 10 '23 at 11:01
0

The new syntax of subscribe :

 this.fetch().subscribe({
        next: (account: Account) => {
            console.log(account);
            console.log("Your code ...");
        },

        error: (e) => {
            console.error(e);
        },

        complete() {
          console.log("is completed");
        },
});
Mady
  • 13
  • 4