Skip to content
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

New rule to disallow assigning to outside scopes #100

Closed
aboyton opened this issue Jun 10, 2019 · 6 comments
Closed

New rule to disallow assigning to outside scopes #100

aboyton opened this issue Jun 10, 2019 · 6 comments
Labels

Comments

@aboyton
Copy link

aboyton commented Jun 10, 2019

Presently there is a rule rxjs-no-unsafe-scope which disallows using variables from an outside scope inside an operator callback. I think it would be useful to also have a similar rule that disallows assigning to an outside scope from inside a callback. In my experience this is often a code smell and can lead to strange bugs. Instead I try and make all class variables either observables or non-observables for a particular class.

For example, to take the example from https://medium.com/@paynoattn/3-common-mistakes-i-see-people-use-in-rx-and-the-observable-pattern-ba55fee3d031

initialize() {
  let id;
  this.appParameters.subscribe(params => id = params['id']);
  if (id !== null && id!== undefined) {
    this.getUser(id).subscribe(user => this.user = user);
  }
}

would instead (at least for Angular) be better written as

initialize() {
  this.user$ = this.appParameters.pipe(
    switchMap(params => {
      const id = params['id'];
      if (id !== null && id !== undefined) {
        return this.getUser(id);
      }
    }),
  );
}

and then you can do user$ | async in the template.

@cartant cartant added the bug label Jun 10, 2019
@cartant
Copy link
Owner

cartant commented Jun 10, 2019

Thanks. This is an oversight - and, therefore, a bug - the rule should definitely flag these situations as failures.

@aboyton
Copy link
Author

aboyton commented Jun 10, 2019

It might be nice to have this as a seperate rule, or at least being able to configure the options for read and write separately. I think I can see a use case for say reading properties but not writing to them, or maybe I should just be cleaning up my code to do neither. That said, being able to turn them on separately might allow easier migration.

@cartant
Copy link
Owner

cartant commented Jun 10, 2019

Hmm, I'm not sure it's necessary. I think writing them is far worse than reading them. The use case you mentioned was pretty much the reason I wrote the rule in the first place. Why I don't have tests that specifically address that, IDK, but people copying data into class state is a pet peeve of mine.

@cartant
Copy link
Owner

cartant commented Jun 10, 2019

I'll have a look at this, later. I have no problem changing my mind if I've remembered things incorrectly or if adding options turns out to look worthwhile, but, ATM, I'm not inclined to add options to this rule.

cartant added a commit that referenced this issue Jun 11, 2019
@cartant
Copy link
Owner

cartant commented Jun 11, 2019

It's definitely a bug. Assignments should also effect a failure. There are tests for assignment to an out-of-scope variable:

of(1).pipe(map(value => outer = value)).subscribe();
~~~~~ [no-unsafe-scope]
of(1).pipe(map(function (value) { return outer = value; })).subscribe();
~~~~~ [no-unsafe-scope]

I just didn't include an assignment to a property. Doing so should effect a failure, by default.

@cartant
Copy link
Owner

cartant commented Jun 11, 2019

An allowSubscribe option has been added to the rule in 4.24.0. The option defaults to true - the rule's previous behaviour.

The problem wasn't the assignment. It was that callbacks within subscribe were ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants