ViewModel hot code push errors

I’m transitioning to using manuel:viewmodel but updates to the HTML side of things resulting in a hot code push cause the following error on the client:

Uncaught RangeError: Maximum call stack size exceeded
    at ejson.js?hash=0f17ced…:530
    at Function._.each._.forEach (underscore.js?hash=cde485f…:157)
    at Object.EJSON.clone (ejson.js?hash=0f17ced…:530)
    at ejson.js?hash=0f17ced…:531
    at Function._.each._.forEach (underscore.js?hash=cde485f…:157)
    at Object.EJSON.clone (ejson.js?hash=0f17ced…:530)
    at ejson.js?hash=0f17ced…:531
    at Function._.each._.forEach (underscore.js?hash=cde485f…:157)
    at Object.EJSON.clone (ejson.js?hash=0f17ced…:530)
    at ejson.js?hash=0f17ced…:531

This error occurs even if I update a standard Blaze Template (non-viewmodel) that’s on the same page as a viewmodel template.

If I take viewmodel out of the page, Blaze hot code pushes go back to working like normal.

I’m new to viewmodel so it could be user error, but everything works fine if I manually refresh the page between edits.

Any ideas why this is happening or where I should start troubleshooting it?

That’s odd, please make a repro.

I’ve been experiencing a similar issue too. I haven’t been able to nail down exactly what causes it, but it seems to happen once a page reaches a certain complexity. It works fine, but when I make a change and Blaze issues the hot code push it crashes with the same RangeError: Maximum call stack size exceeded. Similar stack trace:

    at Object.EJSON.clone (ejson.js?hash=0f17ced…:498)
    at ejson.js?hash=0f17ced…:531
    at Function._.each._.forEach (underscore.js?hash=cde485f…:157)
    at Object.EJSON.clone (ejson.js?hash=0f17ced…:530)
    at ejson.js?hash=0f17ced…:531
    at Function._.each._.forEach (underscore.js?hash=cde485f…:157)
    at Object.EJSON.clone (ejson.js?hash=0f17ced…:530)
    at ejson.js?hash=0f17ced…:531
    at Function._.each._.forEach (underscore.js?hash=cde485f…:157)
    at Object.EJSON.clone (ejson.js?hash=0f17ced…:530)

Interestingly, in the same app, I have simpler pages that don’t exhibit the problem.

It may not be ViewModel related – something similar used to happen when using Autoform. I would sure like to figure out what the issue is, though. I’ll post up with more if I narrow it down further.

Could it be the number of properties in a VM? I’ve done performance tests with thousands of properties but I don’t remember testing if such a VM supports HCP. Can you test a VM with 1k properties?

I spent some time on the problem this morning, and found that I could fix one of my problem pages by loading and initializing a Google Maps component outside of a ViewModel. I had been previously doing that inside the onRendered callback of the page’s main ViewModel, and I guess the size of google.maps object meant that it wouldn’t take many duplications to blow the stack.

I guess my notion of how memory is managed in Javascript is a little fuzzy – I would have expected that objects were held by reference rather than by value, and only the handle would take up room on the stack.

It may be important to point out that I wasn’t storing the big object as a property; it was all just held in variables local to that callback.

All that aside, I’ll do what you ask and test a VM with 1000 properties to see how it handles a hot code push.

I put together the following VM:

Template.VMTest.viewmodel({
   onCreated() {
      for(let i=0; i < 1000; i++) {
         this.load({
            ["Property-" + i]: i,
         });
      }
   },
});

It worked fine. Made an innocuous change to the source file, and the HCP also handled it without complaint.

I remember having a ton of these six months ago: I always debugged the culprit with Chrome Devtools and was able to fix it, too bad I can’t remember what it was. It was a pattern or way of using ViewModel that triggered this behavior. It was possible to fix via code changes (which is why I didn’t submit an issue) but in the end I just turned hot code push off.

I think @colinf is on the right track with his guess about saving the Google Maps instance to a VM prop…

Hey @arggh, thanks for weighing in. I said that I wasn’t holding a google.maps.Map as a property and that I was still experiencing the problem with HCP … but it turns out I was wrong. I was still holding a google.maps.Marker in a property, which holds a reference to a map. Thanks for prompting me to have another look at that.

After having fully moved those big objects from properties to local variables in the callback, the problem clears up.

1 Like