Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Angular binding causing Maximum call stack size exceeded #15712

Closed
AvraamMavridis opened this issue Feb 15, 2017 · 4 comments
Closed

Angular binding causing Maximum call stack size exceeded #15712

AvraamMavridis opened this issue Feb 15, 2017 · 4 comments

Comments

@AvraamMavridis
Copy link

I have a very simple component, something like

App.component('mxComponentOverlay', {
  template: '<div></div>',

  bindings: {
    input: '=?',
  },

  controller: ComponentOverlay,
});

Input is an object, so I am doing:

  <mx-component-overlay
     input="{ 'icon': 'add', 'subject': $ctrl.subject }">
  </mx-component-overlay>

$ctrl.subject was an RxJS 4, Subject, migrating to RxJS 5 this is causing a Maximum call stack size exceeded error.

If I do:

  <mx-component-overlay
     input="$ctrl.subject">
  </mx-component-overlay>

I dont have the issue. Any idea what can cause this?

@gkalpak
Copy link
Member

gkalpak commented Feb 15, 2017

It is not clear whether this issue is Angular-relatd or RxJS-related. Can you provide a demo (e.g. using CodePen, Plnkr etc)?

@gkalpak gkalpak added this to the Purgatory milestone Feb 15, 2017
@AvraamMavridis
Copy link
Author

@gkalpak Minimum example that reproduces the issue.

RxJS 5.1.0
Angular 1.5.1

JS

var app = angular.module('jsbin', []);

app.component('mxComponentOverlay', {
  template: '<div>Rx</div>',
  bindings: {
    input: '<'
  },
  controller: function(){
     this.input.subject.subscribe((data) => console.log(data))
  }
});


app.component('mxComponent', {
  template: '<mx-component-overlay input="{ subject: $ctrl.input }"></mx-component-overlay>',
  controller: function(){
    this.input = new Rx.Subject();
  }
});

HTML

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Angular JS</title>
</head>
<body ng-app="jsbin">
  <mx-component></mx-component>
  <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.1/angular.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.1.0/Rx.js"></script>
  </body>
</html>

jsbin

@gkalpak
Copy link
Member

gkalpak commented Feb 16, 2017

It seems that Rx.Subject has changed in a way that is no longer compatible with angular.equals(). Since you are using it in an object literal binding (input="{subject: $ctrl.someRxSubject}"), a new object will be created on each $digest and Angular will try to determine if it equals with the previous one (and break because of the new Rx.Subject implementation).

We have improved the way object/array literals are watched in #15301, but the change will land in 1.6.3. Here are your options:

  1. Update to v1.6.3 (once it is released later this month) - heads-up: There are some breaking changes.
    You can see it in action here.

  2. Instead of binding to an object literal containing the Rx.Subject, create the object in your controller and bind to that (or bind to the Rx.Subject directly).
    You can see these approaches in action here and there.

Closing, since we have already made the necessary improvements.

@AvraamMavridis
Copy link
Author

@gkalpak thx a lot.

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

No branches or pull requests

2 participants