-
Notifications
You must be signed in to change notification settings - Fork 25.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
angular 9 / Ivy => async 'as' leads to error #34405
Comments
Looks like it was made intentionally according to Ivy Compatibility Guide
|
Thanks for the answer. Looks like a rough BC break, as this pattern looks very common to me. Anyway, how are we supposed to refactor this kind of code ? And as I said, it does not look like Ivy specific, as disabling Ivy pops an error too regarding template variable assignment. Thanks again for feedback. |
It is not clear what you are trying to achieve (i.e. what the expected/ideal behavior would be) with Just to be clear, the error is not related to <app-search-filter [(applicationsList)]="applicationsList"></app-search-filter> This is syntactic sugar for a two-way binding. It is equivalent to: <app-search-filter [applicationsList]="applicationsList" (applicationsListChange)="applicationsList = $event"></app-search-filter> It's this second part ( (Finally, as mentioned in the guide, the compiler would previouly ignore the assignments, so this change will not break something that used to work before. It will only turn silent failing at runtime to hard failing at compile time.) |
Indeed, this repository is just a sandbox to experiment misc things in a quick and dirty way. The full code is irrelevant (even if working with angular 8) and clumsy. The main idea is just giving the aliased ('as') observable (an array of strings) from a parent component to a child component, filtering the array in the child component based on a search term the user types in a simple input field, and with the 'banana in the box', displaying the filtered array in the parent component. This is something that works today with ng8, it does not fail silently at runtime as you suppose it does. Again, It's not a real world app, but it just works.
It just does not fail at runtime today :) Here is the full extract <div id="app" *ngIf="(applicationsList$ | async) as applicationsList">
<app-search-filter [(applicationsList)]="applicationsList"></app-search-filter>
<table id="mytable">
<tr *ngFor="let application of applicationsList">
<td>
<fav-star [application]="application">
{{application.name}} <span *ngIf="application.isFav">(faved !)</span>
</fav-star>
</td>
</tr>
</table>
{{applicationsList | json}}
</div> And just to be clear, without Ivy, it fails too. I understand that this not acceptable anymore in ng9, Ivy or not, but I think that this kind of double-binding is quite common. (ie, passing a value from parent to child, and displaying in the parent a computed value). BC breaks are really acceptable, particularly in a 9th version :) I just think this is something that is over used today. But I have no problem in the fact that this not a possibility anymore. But I'm exploring migration path from v8 to v9. Thanks for your valuable feedback. |
Thanks for clarifying. That sounds weird, though. Could you show how the filtering is done? What is important here is whether that is done by mutating an array or by creating a new one. |
This is done here : https://github.com/mpalourdio/ng2/blob/7f3a9b6114c04b37c664fe55a73ee1bd06fa061d/src/app/search-filter/search-filter.component.ts#L33 Feel free to just clone this repo, running it on ng8 (current yarn.lock), and upgrading it to angular@next if needed. It emits a new array from child to parent (so the child keeps track of the original array) (== array#filter), so there's no mutation of the original reference. The ugly |
@mpalourdio I am amazed this ever worked! |
That's what makes angular amazing :). Apart the very poor code quality, what is fundamentally wrong here? |
I created this StackBlitz project and it does indeed work with v8 💥 So, this sounds like a breaking change that needs to be documented. @JoostK, do you know what's the case for template variables created via
@mpalourdio: This seems like a big anti-pattern (and I hope it is not as common as you say 😅). The main issue I see is that the So, my expectation when I first looked at the component (and the reason I immediately thought "this can't be right" 😁) was that The only reason the component works in this case is that it uses the In addition, you open yourself up to all sorts of subtle bugs, such as:
Of course, you can work around them, but the point is that the parent-component behavior may change due to the implementation of a child-component and detailed knowledge of the child-component's implementation is needed in order to make the parent-component/template work as intended. |
That's really clear for me! Thanks a lot for these great explanation, and for taking time to investigate. So far, again, that's really a quick and dirty project and I wanted to give feedback on the migration path. Feel free to close this issue, as it's really not an issue ('cause I am the issue :p). Thanks again! |
The issue is that this breaking change is not (clearly) documented, so let's keep this open to track that 😃 Action items:
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Im curious if this is an anti-pattern, how do you do this instead? thanks you here is a stackblitz (look console output) |
This comment has been minimized.
This comment has been minimized.
@DomEscobar Basically, you just need to stash that value somewhere other than a template variable. |
Closing since it seems like this was a change for v9 and we're already pretty far out from that and it seems like this haven't been an issue that has affected a large number of users. |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
🐞 bug report
Affected Package
https://github.com/mpalourdio/ng2
Is this a regression?
Yes, the previous version in which this bug was not present is angular8@latest.
Description
yarn start
Error :
Property 'applicationsList' does not exist on type 'ChildComponent'. Did you mean 'applicationsList$'?
Disabling Ivy leads to
ERROR in Cannot assign value "$event" to template variable "applicationsList". Template variables are read-only.
🔬 Minimal Reproduction
ng update @angular/cli @angular/core --next
🔥 Exception or Error
Disabling Ivy leads to
ERROR in Cannot assign value "$event" to template variable "applicationsList". Template variables are read-only.
🌍 Your Environment
Angular Version:
EDIT (by gkalpak)
Adding the conclusions from #34405 (comment) (after the discussion below) here for visibility:
The text was updated successfully, but these errors were encountered: