-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refine subscribe and tap signatures #4159
Comments
I think we can have tslint rules easily, that's probably not a problem. For librarywise, I'd like to think bit more: specifically, you'd like to allow form of
but do not allow any other forms? or it is still allowed
form? |
It would be allowed in the short term, but in the long term (next major version or some future major version), it would be a hard API change. |
And if anyone is wondering "why not just I'd expect that |
I agree it's major usecase, but not sure about 90%. i.e these two form
I've been used all time, personally I never used observer object form ( what if we allow fn form as is, only disallow optional form?
|
I'm all for this change; in fact I've recently started doing I'd like to discuss the "Con" a bit more:
Do you have more specifics about this? It seems like
I don't fully agree with this for a couple of reasons:
|
I honestly could not agree more. With our work with RxJS, we've had so many bike shedding discussions due to this issue and the students I've helped teach RxJS often get caught on this issue (of error handling/syntax) based on the numerous ways to approach things and the different (usually 3rd party) resources. |
What I specifically like about |
I agree with this. I found having the |
From the core team meeting: Start with deprecating signatures like |
BTW, there is a TSLint rule in |
Although I agree that observer syntax is a bit more readable, it is not always a win in practice. Consider the following code: class A {
private status = false;
private subscription: Subscription | null = null;
constructor(private readonly obs: Observable<any>) {}
someMethod() {
this.subscription = this.obs.subscribe(value => {
// notice the usage of this here
this.status = true;
}, err => {
// some error handling
});
}
} When attempting to transform this code to observer syntax, it fails on unavailability of "this". Moreover, readability in a good editor (like IntelliJ Idea) is better, because the IDE shows parameter names. It looks like this: class A {
private status = false;
private subscription: Subscription | null = null;
constructor(private readonly obs: Observable<any>) {}
someMethod() {
this.subscription = this.obs.subscribe(next: value => {
// notice the usage of this here
this.status = true;
}, error: err => {
// some error handling
});
}
} I would appreciate any suggestions how to transform this code to observer syntax with retaining availability of "this". If that is not easily possible, I'd vote for un-deprecating these methods. |
@sebek64 The only difference between your second snippet and the observer syntax is two enclosing braces. Well, that and that fact that your snippet isn't valid TypeScript. |
@cartant Yes, it isn't a valid typescript. It is how the code is displayed by Idea. The added argument names "next" and "error" and in a different font (smaller, grey). |
class A {
private status = false;
private subscription: Subscription | null = null;
constructor(private readonly obs: Observable<any>) {}
someMethod() {
this.subscription = this.obs.subscribe({
next: value => this.status = true,
error: err => { /* ... */ }
});
}
} |
@cartant Thanks, this works. I haven't realized that this syntax is possible in Typescript. So in this case it is a good idea to keep the deprecations :) |
@benlesh Do we agree this is still OK in v6.4 and further? someObservable.subscribe(() => {}); Because when doing that, TypeScript IntelliSense is showing a signature flagged as deprecated since v6.4... And it's not clear if the following are still OK or not: someObservable.subscribe(() => {}, () => {}); someObservable.subscribe(() => {}, () => {}, () => {}); |
After some investigation, the deprecated descriptions are shown by IntelliSense in all cases! TypeScript doesn't support to have different JSDoc for different overloads. TypeScript will aggregate all the JSDoc available for the function. It creates a very confusing situation... |
I like the change that was done in #4202 to support this discussion. However, it seems that now observables that I convert from other libs (e.g. mobx-utils, see simplistic mobxjs/mobx-utils#138) don't compile.
|
@samybaxy That's a bug/feature of the pop-up window that's shown in the editor. The summary of the deprecated messages is shown for all usages of |
Along with @fetis I would concur that this.http.get<Item[]>(`/api/item/getItems`)
.subscribe(
data => this.items.next(data),
err => this.snacker.sendErrorMessage(err.error)
) |
I wonder why anyone didn't stop for a moment wondering if deprecating working code in large codebases was such a great idea. The signature with 3 callbacks is a natural extension of the Promise A (1) Optional linting rules for teaching, (2) exposing more of the "recommended" syntax, (3) producing an automated tool to mechanically convert from one version to the recommended one: those are fine. Breaking the build for medium or large (50k lines of code) codebases WITHOUT any functional advantage IS NOT GOOD, people. Please, please stop breaking my code at any upgrade. And don't tell me that a major is breaking by definition and everything is fine, because it's not: hundreds of deprecation warnings, just for the sake of it, in my build are definitely not fine. |
And, regarding the initial post: you're inflating numbers. Mnemonically we have only two signatures: o.subscribe(fn | null, fn | null, fn | null);
o.subscribe(observer); |
@alberto-chiesa Thankfully we are not the only ones wondering about those changes. Question towards the the collaborators: Will there possibly atleast be schematics to fix those deprecations when the code is actually removed (I would have loved to have the schematics along with the deprecation). |
@pfeigl I think no one is caring enough about the sanity of existing developers using this library. A breaking change such as I love RxJS, I'm an absolute fan of it, but keep in mind that enterprise environments are a thing! Please, please, please, keep it stable. If the only advantage is "readability" and it can break something, the trade off should NOT be considered. You carry the responsibility of thousands of codebases. Readability is important, but it should not break the build. |
* docs(subscribe): add comma after "In particular" * docs(subscribe): add notice about asynchronously thrown errors * docs(subscribe): add notice about deprecated usages of `subscribe` method (relates to ReactiveX#4159) * docs(subscribe): add notice about using `subscribe` with no params * docs(subscribe): fix example not to use deprecated `subscribe` * docs(subscribe): add example with deprecated `subscribe` with notice that it's deprecated * docs(subscribe): fix unsubscribe example replacing deprecated `subscribe` usage with Observer * docs(subscribe): add notice that unprovided error handlers will cause throwing errors asynchronously * docs(subscribe): fix return type Closes ReactiveX#5339
Could we create an ESLint rules with an autofixer that converts the deprecated signatures to the object signature? This could serve as an automatic migration script to make upgrading painless (and hopefully aid in adapting before the new version is even out). The intermediate state with all these deprecation notices and many overloads definitely has a cost. cc @cartant who has the excellent https://github.com/cartant/eslint-plugin-rxjs |
@felixfbecker There are a bunch of deprecations that I think need reconsideration - the |
@benlesh I've just read your issue itself....and in all honesty, I frequently use these signatures myself:
I've never used the versions with void...not sure if that means you could just pass void, or it just means passing My honest opinion here is, if all but the last two cases break if I upgrade to RxJs 7, I'll be delaying that upgrade for quite some time. I understand the desire to simplify...but something I feel very strongly about is that the javascript community is far too disinterested in backwards compatibility, and in the long run that puts a lot of burden on developers, on companies...on our clients funds...do deal with the never-ending train of breaking changes. As an example, I endured quite a lot of pain across many projects to deal with the Ionic 3 -> Ionic 4 upgrades...which was a very poorly supported upgrade path. The cost burden to deal with it went to my clients, of course...but it was a frustrating experience each time for myself and other devs as well. I would hate to see RxJs 7 impose the same kind of frustration. I think we should be cognizant of that when making decisions that will force upgraders to endure a lot of pain in the process. I'm also an avid gamer, and I'm definitely in the camp of gamers who staunchly support delaying the game release, if it means getting the game right, with as few bugs as possible, on release. I feel the same way about libraries like RxJs...I would much rather time be spent to make the RxJS 7 release a smooth one that doesn't put a lot of pain on the developer, or drain on our clients budgets, to deal with tons of breaking changes, or migration issues, etc. than to have it rushed out before the end of the year...just to get it out before the end of the year. My honest thoughts (I suspect I'll be sharing more...this is the first of the checklist I've taken a look at.) |
Hello, in the vast majority of our code, we use the signature subscribe is deprecated: Use an observer instead of a complete callback (deprecation)tslint(1) This is an Angular 11 project with rxjs 6.5.4. |
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. |
It seems that a new Typescript SDK version (or a combination of a specific Typescript version with a specific TSLint plugin version) causes this. A project that I'm working on has this exact problem even though it's dependencies haven't been updated for months. Set the Typescript SDK to the older version in node_modules works for me. |
* docs(subscribe): add comma after "In particular" * docs(subscribe): add notice about asynchronously thrown errors * docs(subscribe): add notice about deprecated usages of `subscribe` method (relates to ReactiveX#4159) * docs(subscribe): add notice about using `subscribe` with no params * docs(subscribe): fix example not to use deprecated `subscribe` * docs(subscribe): add example with deprecated `subscribe` with notice that it's deprecated * docs(subscribe): fix unsubscribe example replacing deprecated `subscribe` usage with Observer * docs(subscribe): add notice that unprovided error handlers will cause throwing errors asynchronously * docs(subscribe): fix return type Closes ReactiveX#5339
* docs(subscribe): update `subscribe` documentation * docs(subscribe): add comma after "In particular" * docs(subscribe): add notice about asynchronously thrown errors * docs(subscribe): add notice about deprecated usages of `subscribe` method (relates to #4159) * docs(subscribe): add notice about using `subscribe` with no params * docs(subscribe): fix example not to use deprecated `subscribe` * docs(subscribe): add example with deprecated `subscribe` with notice that it's deprecated * docs(subscribe): fix unsubscribe example replacing deprecated `subscribe` usage with Observer * docs(subscribe): add notice that unprovided error handlers will cause throwing errors asynchronously * docs(subscribe): fix return type Closes #5339 * docs: minor grammar tweaks And remove specific mention of deprecations. Let the signature deprecations to the talking. * docs: more minor tweaks Co-authored-by: Nicholas Jamieson <nicholas@cartant.com>
This is done and in 7.x. |
I use RxJS in an enterprise large Angular codebase and I've just upgraded Angular to 15.2 and RxJS to 7.8. A simple search for .subscribe in my main project returns 1185 results. I'm seeing a lot of deprecated .subscribe method calls and to be honest, it's frustrating. |
@florinr1 if I'm not mistaken, if you follow the angular upgrade guide and use the angular cli to upgrade, these RxJs signature changes should be taken care of automatically. |
Currently we have a variety of ways you can use
subscribe
and tap:It's been my personnel recommendation that people stick to the following two signatures:
The reason being is:
Proposal
I'd like to deprecate the other signatures to
subscribe
andtap
, and narrow down the signature to just those two prescribed above for the next major versionPros
Cons
catchError
orretry
-type operator, rather than in the subscribe.)Other thoughts
It would also be good to add some lint rules around this to rxjs-tslint and the like.
The text was updated successfully, but these errors were encountered: