Skip to content

Alpha35: Empty event expression produce cryptic error #3754

Closed

Description

@cghislai

Related: #3664 (should be fixed together)

I have a template with the following element:

<input type="file" id="picture" accept="image/*"
                           (change)="onFileSelected(f, $event)"
                           (fileread)>

On alpha 33 it worked great.
On alpha35 it produces the following runtime error:

EXCEPTION: TypeError: Cannot set property 'lastInBinding' of undefined
angular2.js:13030 STACKTRACE:
angular2.js:13030 TypeError: Cannot set property 'lastInBinding' of undefined
    at Function.execute._ConvertAstIntoProtoRecords.create (http://localhost:5555/lib/angular2.js:18104:47)
    at http://localhost:5555/lib/angular2.js:17730:49
    at Array.map (native)
    at createEventRecords (http://localhost:5555/lib/angular2.js:17729:36)
    at JitProtoChangeDetector.execute.JitProtoChangeDetector._createFactory (http://localhost:5555/lib/angular2.js:17575:39)
    at new JitProtoChangeDetector (http://localhost:5555/lib/angular2.js:17567:32)
    at $__1.execute.JitChangeDetection.createProtoChangeDetector (http://localhost:5555/lib/angular2.js:10323:20)
    at http://localhost:5555/lib/angular2.js:15553:42
    at Array.map (native)
    at Function.execute.ListWrapper.map (http://localhost:5555/lib/angular2.js:6374:26)

The following modification still produces the error:

<input type="file" id="picture" accept="image/*"
                           (change)="onFileSelected(f, $event)"
                           (fileread)="">

This one works

<input type="file" id="picture" accept="image/*"
                           (change)="onFileSelected(f, $event)"
                           (fileread)="x">

Activity

  1. pkozlowski-opensource commented on Aug 20, 2015

    @pkozlowski-opensource
    Member

    @cghislai apart from the regression (?) that you are seeing here- what would be the case for having an empty event handler? I mean - if you don't take any action on a given event, why adding (fileread) at all?

    I would say that in this case we should simply throw a good error, but maybe you've got a valid use-case?

  2. cghislai commented on Aug 20, 2015

    @cghislai
    Author

    It was an hack.
    I had a filereader that read the file then stored the dataURI in a field. I had an img component with the src attributed bound to that dataURI field. The issue was that the img was not reloaded once the file was read. Triggering that event triggered change detection and the image was updated.

    I now moved that job in a Promise, and update the dataURI field in the then clause, and image updates automatically.

  3. pkozlowski-opensource commented on Aug 20, 2015

    @pkozlowski-opensource
    Member

    OK, so from what I understand it was simply a way of hacky way of kicking-off change detection, right?

    If so, let's solve this issue by introducing better checks / error messages for missing event handlers. How does it sound?

  4. cghislai commented on Aug 20, 2015

    @cghislai
    Author

    Sounds good. That was the main point of this issue.

  5. LinboLen commented on Aug 26, 2015

    @LinboLen

    It sames execute _ConvertAstIntoProtoRecords.create, rec is still empty array

      static create(b: BindingRecord, variableNames: List<any>): ProtoRecord[] {
        var rec = [];
        _ConvertAstIntoProtoRecords.append(rec, b, variableNames, null);
        rec[rec.length - 1].lastInBinding = true;
        return rec;
      }
    

    its append first, but some ast visit execute nothing,such as ASTWithSource

      static append(records: List<ProtoRecord>, b: BindingRecord, variableNames: string[],
                    bindingIndex: number) {
        var c = new _ConvertAstIntoProtoRecords(records, b, variableNames, bindingIndex);
        b.ast.visit(c);
      }
    
  6. gionkunz commented on Sep 16, 2015

    @gionkunz
    Contributor

    So how would we go about specifying where we need change detection? Working with simple view locals this can be very handy:

        <svg-component [width]="width.value" [height]="height.value" color="red"></svg-component>
        <div>
          <label>width:
            <input #width type="number" value="100" (input)/>
          </label>
        </div>
    
        <div>
          <label>height:
            <input #height type="number" value="100" (input)/>
          </label>
        </div>

    In earlier versions I was using this "hack" to trigger change detection based on events. Now I can't do this anymore unless I would like to update my directive model, which sometimes I might don't want to when working with simple view locals.

    Is there an other best practice I'm missing here?

    Cheers

  7. 2 remaining items

  8. pkozlowski-opensource commented on Sep 17, 2015

    @pkozlowski-opensource
    Member

    Right - we should definitively update examples then.

  9. alxhub commented on Nov 20, 2015

    @alxhub
    Member

    @pkozlowski-opensource I actually agree that <input #var (keyup)> is a desirable feature, not a hack. It indicates "This event is meaningful to my component" even if the component itself has no code to run for the event. I think forcing a pattern where people write (keyup)="noopHandler()" with an empty function in the component is more of a hack.

    Note that <input (keyup)="null"> does work currently.

  10. pkozlowski-opensource commented on Nov 20, 2015

    @pkozlowski-opensource
    Member

    @alxhub

    It indicates "This event is meaningful to my component" even if the component itself has no code to run for the event.

    Why it would be meaningful to a component if no code is executed in response? Do you have a use-case where this pattern would be an elegant solution? All the use-cases I've seen so far involved repeated reading from the DOM and I don't think we want to encourage it.

    Note that <input (keyup)="null"> does work currently.

    This is why I was saying that we should throw :-)

    Personally I don't mind if we support this or not, but I'm afraid of promoting a pattern that involves reading from the DOM all the time.

  11. acdcjunior commented on Feb 7, 2016

    @acdcjunior

    +1

    I got the same error: EXCEPTION: TypeError: Cannot set property 'lastInBinding' of undefined at beta.3 while trying out the very same example from https://angular.io/docs/js/latest/guide/user-input.html#local-variables .

    I understand you guys are already on it, but, regardless of what you decide, the current error message, coupled with the tutorial, is very misleading - bad, specially for those first trying the new version.

  12. zamrokk commented on Mar 24, 2016

    @zamrokk

    👍 this still exists on beta-9

  13. johnarchuletta commented on May 7, 2016

    @johnarchuletta

    This error is still occuring in RC1 when using something like <a (click)></a>).

    (Forgot to add handler to an anchor element and Chrome spit this out)

    browser_adapter.ts:88 EXCEPTION: TypeError: Cannot read property 'visitStatement' of undefined
    2016-05-07 07:15:03.983 browser_adapter.ts:78 EXCEPTION: TypeError: Cannot read property 'visitStatement' of undefinedBrowserDomAdapter.logError @ browser_adapter.ts:78BrowserDomAdapter.logGroup @ browser_adapter.ts:89ExceptionHandler.call @ exception_handler.ts:53(anonymous function) @ application_ref.ts:341ZoneDelegate.invoke @ zone.js:323NgZoneImpl.inner.inner.fork.onInvoke @ ng_zone_impl.ts:67ZoneDelegate.invoke @ zone.js:322Zone.run @ zone.js:216(anonymous function) @ zone.js:571ZoneDelegate.invokeTask @ zone.js:356NgZoneImpl.inner.inner.fork.onInvokeTask @ ng_zone_impl.ts:56ZoneDelegate.invokeTask @ zone.js:355Zone.runTask @ zone.js:256drainMicroTaskQueue @ zone.js:474ZoneTask.invoke @ zone.js:426
    2016-05-07 07:15:03.985 browser_adapter.ts:88 EXCEPTION: Error: Uncaught (in promise): TypeError: Cannot read property 'visitStatement' of undefined
    2016-05-07 07:15:03.985 browser_adapter.ts:78 EXCEPTION: Error: Uncaught (in promise): TypeError: Cannot read property 'visitStatement' of undefinedBrowserDomAdapter.logError @ browser_adapter.ts:78BrowserDomAdapter.logGroup @ browser_adapter.ts:89ExceptionHandler.call @ exception_handler.ts:53(anonymous function) @ application_ref.ts:304schedulerFn @ async.ts:131SafeSubscriber.__tryOrUnsub @ Subscriber.ts:240SafeSubscriber.next @ Subscriber.ts:192Subscriber._next @ Subscriber.ts:133Subscriber.next @ Subscriber.ts:93Subject._finalNext @ Subject.ts:154Subject._next @ Subject.ts:144Subject.next @ Subject.ts:90EventEmitter.emit @ async.ts:117NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError @ ng_zone.ts:138NgZoneImpl.inner.inner.fork.onHandleError @ ng_zone_impl.ts:90ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233_loop_1 @ zone.js:487drainMicroTaskQueue @ zone.js:494ZoneTask.invoke @ zone.js:426
    2016-05-07 07:15:03.985 browser_adapter.ts:78 STACKTRACE:BrowserDomAdapter.logError @ browser_adapter.ts:78ExceptionHandler.call @ exception_handler.ts:56(anonymous function) @ application_ref.ts:304schedulerFn @ async.ts:131SafeSubscriber.__tryOrUnsub @ Subscriber.ts:240SafeSubscriber.next @ Subscriber.ts:192Subscriber._next @ Subscriber.ts:133Subscriber.next @ Subscriber.ts:93Subject._finalNext @ Subject.ts:154Subject._next @ Subject.ts:144Subject.next @ Subject.ts:90EventEmitter.emit @ async.ts:117NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError @ ng_zone.ts:138NgZoneImpl.inner.inner.fork.onHandleError @ ng_zone_impl.ts:90ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233_loop_1 @ zone.js:487drainMicroTaskQueue @ zone.js:494ZoneTask.invoke @ zone.js:426
    2016-05-07 07:15:03.985 browser_adapter.ts:78 Error: Uncaught (in promise): TypeError: Cannot read property 'visitStatement' of undefined
        at resolvePromise (zone.js:538)
        at PromiseCompleter.reject (zone.js:515)
        at eval (application_ref.ts:340)
        at ZoneDelegate.invoke (zone.js:323)
        at Object.NgZoneImpl.inner.inner.fork.onInvoke (ng_zone_impl.ts:67)
        at ZoneDelegate.invoke (zone.js:322)
        at Zone.run (zone.js:216)
        at zone.js:571
        at ZoneDelegate.invokeTask (zone.js:356)
        at Object.NgZoneImpl.inner.inner.fork.onInvokeTask (ng_zone_impl.ts:56)BrowserDomAdapter.logError @ browser_adapter.ts:78ExceptionHandler.call @ exception_handler.ts:57(anonymous function) @ application_ref.ts:304schedulerFn @ async.ts:131SafeSubscriber.__tryOrUnsub @ Subscriber.ts:240SafeSubscriber.next @ Subscriber.ts:192Subscriber._next @ Subscriber.ts:133Subscriber.next @ Subscriber.ts:93Subject._finalNext @ Subject.ts:154Subject._next @ Subject.ts:144Subject.next @ Subject.ts:90EventEmitter.emit @ async.ts:117NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError @ ng_zone.ts:138NgZoneImpl.inner.inner.fork.onHandleError @ ng_zone_impl.ts:90ZoneDelegate.handleError @ zone.js:327Zone.runGuarded @ zone.js:233_loop_1 @ zone.js:487drainMicroTaskQueue @ zone.js:494ZoneTask.invoke @ zone.js:426
    2016-05-07 07:15:03.987 zone.js:461 Unhandled Promise rejection: Cannot read property 'visitStatement' of undefined ; Zone: angular ; Task: Promise.then ; Value: TypeError: Cannot read property 'visitStatement' of undefined(…)consoleError @ zone.js:461_loop_1 @ zone.js:490drainMicroTaskQueue @ zone.js:494ZoneTask.invoke @ zone.js:426
    2016-05-07 07:15:03.989 zone.js:463 Error: Uncaught (in promise): TypeError: Cannot read property 'visitStatement' of undefined(…)consoleError @ zone.js:463_loop_1 @ zone.js:490drainMicroTaskQueue @ zone.js:494ZoneTask.invoke @ zone.js:426
    
  14. JohannesAtGit commented on Jul 28, 2016

    @JohannesAtGit

    Error still occuring in RC4 when using (click)=""

  15. added a commit that references this issue on Aug 1, 2016
    e73d051
  16. angular-automatic-lock-bot commented on Sep 9, 2019

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  17. locked and limited conversation to collaborators on Sep 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions