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

Exception from Meteor.flush: TypeError: Cannot read property '_spark_13e45627-9ca1-47a0-a197-57d332dd69f1' of null #392

Closed
crapthings opened this Issue Oct 14, 2012 · 10 comments

Comments

Projects
None yet
6 participants
@crapthings

crapthings commented Oct 14, 2012

after i click $('.action-update-profile') console log these error, but all form value updated properly
and i click update button again, no error are shown.
then i direct to other page and back this page click update same thing happen?
what's wrong ?

Exception from Meteor.flush: TypeError: Cannot read property '_spark_13e45627-9ca1-47a0-a197-57d332dd69f1' of null
at enclosingRangeSearch (http://localhost:3000/packages/liverange/liverange.js?6aa9b98f3d9213ded0d8fb2aa6c93df8cdfd94e1:653:12)
at Function.LiveRange.findRange (http://localhost:3000/packages/liverange/liverange.js?6aa9b98f3d9213ded0d8fb2aa6c93df8cdfd94e1:633:18)
at LiveRange.findParent (http://localhost:3000/packages/liverange/liverange.js?6aa9b98f3d9213ded0d8fb2aa6c93df8cdfd94e1:628:22)
at findParentOfType (http://localhost:3000/packages/spark/spark.js?8b4e0abcbf865e6ad778592160ec3b3401d7abd2:81:19)
at Object.Spark.renderToRange (http://localhost:3000/packages/spark/spark.js?8b4e0abcbf865e6ad778592160ec3b3401d7abd2:579:18)
at http://localhost:3000/packages/spark/spark.js?8b4e0abcbf865e6ad778592160ec3b3401d7abd2:818:13
at http://localhost:3000/packages/deps/deps-utils.js?f3fceedcb1921afe2b17e4dbd9d4c007f409eebb:78:31
at _.extend.run (http://localhost:3000/packages/deps/deps.js?933d82b6f13dbc7adbc51a6c30bb0f8928f42e98:19:20)
at rerun (http://localhost:3000/packages/deps/deps-utils.js?f3fceedcb1921afe2b17e4dbd9d4c007f409eebb:78:11)
at http://localhost:3000/packages/deps/deps.js?933d82b6f13dbc7adbc51a6c30bb0f8928f42e98:63:15
at Array.forEach (native) 

i have a form and a button act updateUserProfile looks like this

<template name="module-settings-profile">

    <div class="module">
        <div class="flex-module">
            <div class="r">
                <form class="form-horizontal">
                    <legend>用户档案</legend>
                    <div class="control-group">
                        <label for="" class="control-label">显示名</label>
                        <div class="controls">
                            <input type="text" class="data-user-profile-name" value="{{user.profile.name}}">
                        </div>
                    </div>
                    <div class="control-group">
                        <label for="" class="control-label">头衔</label>
                        <div class="controls">
                            <input type="text" class="data-user-profile-honour" value="{{user.profile.honour}}">
                        </div>
                    </div>
                    <div class="control-group">
                        <label for="" class="control-label">QQ</label>
                        <div class="controls">
                            <input type="text" class="data-user-profile-qq" value="{{user.profile.qq}}">
                        </div>
                    </div>
                    <div class="control-group">
                        <label for="" class="control-label">个人/公司网站</label>
                        <div class="controls">
                            <input type="text" class="data-user-profile-website" value="{{user.profile.website}}">
                        </div>
                    </div>
                    <div class="control-group">
                        <label for="" class="control-label">Github</label>
                        <div class="controls">
                            <input type="text" class="data-user-profile-github" value="{{user.profile.github}}">
                        </div>
                    </div>
                    <div class="control-group">
                        <div class="controls">
                            <button type="button" class="btn btn-success action-update-profile">更新</button>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>

</template>

if Meteor.isClient is true

    Template['module-settings-profile'].events =
        'click .action-update-profile': ->
            data =
                name: $('.data-user-profile-name').val()
                honour: $('.data-user-profile-honour').val()
                qq: $('.data-user-profile-qq').val()
                website: $('.data-user-profile-website').val()
                github: $('.data-user-profile-github').val()
            Meteor.call 'updateUserProfile', data, ->
                console.log data

    Template['module-settings-profile'].user = ->
        Meteor.user()
@glasser

This comment has been minimized.

Member

glasser commented Oct 15, 2012

It is much easier for us to fix bugs if provided with a full reproduction recipe with a complete app (ie, starting with "git clone"): https://github.com/meteor/meteor/wiki#wiki-bugs

Also, what browser are you using?

@crapthings

This comment has been minimized.

crapthings commented Oct 16, 2012

i've made a quick example to reproduce the error
i've tried put it to github but mac client always stoping at "pushing to github with no response"

i upload to a random place
http://www.2shared.com/file/7k8A9VX-/error-testing.html?

this example use mrt create --branch devel
package used backbone i think the main issue is
i use backbone router.navigate to redirect page it causes a spark error.

  1. make two page for page switch by using backbone.router.extend
  2. make a page with some Reactivity by using Collection update
  3. use a router.navigate with 2nd arg = true, page seems switchy faster than use a normal redirect. but
    it will produce error
@glasser

This comment has been minimized.

Member

glasser commented Nov 1, 2012

OK, we've made a minimal reproduction for this.

$ git clone https://github.com/glasser/meteor-issue-392.git
$ cd meteor-issue-392
$ meteor

Click the link, type something into the box, open JS console, click button, see error.

The issue is zombie templates: Spark is re-rendering stuff offscreen.

@wojtekgalaj

This comment has been minimized.

wojtekgalaj commented Nov 6, 2012

Removing a template from the dom will not trigger Meteor's destroyed callback nor will it do all the necessary cleanup. To solve it, use Spark directly, like so:

Spark.finalize($(container)[0]);

I have added this to my render method. It would be nice for Meteor to handle this. :)

@crapthings

This comment has been minimized.

crapthings commented Nov 6, 2012

@wojtekgalaj it's really hard to understand, could u pls give more example ?

@wojtekgalaj

This comment has been minimized.

wojtekgalaj commented Nov 6, 2012

Calling Spark.finalize passing a DOM element will clean up all the bindings, events and all the reactive mechanisms Meteor provides thus taking care of the zombie templates. There might be a cleaner way to do this but for now, the solution below works for me.

Here's my render method:

function render(tmpl, container, options) {
  container = container || '#main_container';
  var template = Meteor.render(function () {
    return Template[tmpl]();
  });
  Spark.finalize($(container)[0]);
  $(container).html(template);
}
@rtfeldman

This comment has been minimized.

rtfeldman commented Nov 23, 2012

I was having the same issue, and @wojtekgalaj's workaround fixed it. Thanks!

@dgreensp

This comment has been minimized.

Contributor

dgreensp commented Jan 3, 2013

Fixed on devel.

Spark.finalize() is a good way to go because it ensures that the template is garbage collected. However, it is now safe to manually take templates off the screen, and they will be garbage collected when they are invalidated.

I'm pretty sure this is a regression from the early days of Meteor that was introduced when we moved around the code that checks whether a template has left the document.

Thanks for everyone's work and patience!

@dgreensp dgreensp closed this Jan 3, 2013

@scottburch

This comment has been minimized.

scottburch commented Jan 3, 2013

@dgreensp: Does this mean that destroyed() will be called if I manually remove a template, or only if I call .finalize()?

@dgreensp

This comment has been minimized.

Contributor

dgreensp commented Jan 3, 2013

Ah, good question. Spark will discover that a template has been taken off the screen when it goes to update it, and then it will try to finalize that whole chunk of DOM. However, if you don't take the template out of the DOM "in one piece," which basically means the parent node of the template is removed at the same time, I'm not sure Spark can do it.

So if you want immediate, reliable destroyed() callbacks, use .finalize().

dgreensp added a commit that referenced this issue Jan 3, 2013

Fix #392 - Spark.isolate prints stack trace
Isolates would print a stack trace upon re-render
if their DOM nodes had been manually removed from
the DOM without called Spark.finalize.

glasser added a commit that referenced this issue Jan 3, 2013

glasser added a commit that referenced this issue Jan 3, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment