Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Cannot read property 'detach' of null after using Tipped.remove

I am using Tipped in a knockout js application and I'm having an issue when trying to remove Tipped instances. I am using a knockout js component and passing in the correct target. I have checked and it appears as though the tipped instance is being removed but I am getting an error each time I remove the instance.

Uncaught TypeError: Cannot read property 'detach' of null

The error points to this section:
detach: function() {
this.options.detach && !this.is("detached") && (this._tooltip.detach(), this.is("detached", !0))
},

Comments

  • How do I recreate this with minimal code?
    If you console.log(this.options, this._tooltip); at the top of that function what does it say?

    If this._tooltip is null it might be that the tooltip itself is removed from the DOM before calling Tipped.remove() on the target. Can only guess what would be causing that removal. If this is the problem you can fix it by calling Tipped.remove() earlier. Tipped should probably also guard against errors whenever third party code removes its elements.
  • I added those logs and checked it out. I've converted this.options to JSON and copied below, while this._tooltip is null

    I have tried 2 methods. The first was to remove the Tipped instance when the component was being disposed but thinking that the element was null at that point I then tried to remove it in the afterHide event, e.g.

    ...
    afterHide: function(c,e){
    Tipped.remove(e);
    },
    ...

    .. but the issue is that once the element has been hidden it is essentially null. By the way, if I don't remove the instance I end up just getting duplicate Tipped's created and they end up stacking on top of one another.

    ----- OUTPUT HERE -----
    FYI - I've deleted a couple attributes here. Namely functions (afterHide, onShow, etc) and container to enable conversion to JSON.

    "{"ajax":false,"cache":true,"containment":{"selector":"viewport","padding":5},"close":false,"detach":true,"fadeIn":200,"fadeOut":200,"showDelay":75,"hideDelay":300,"hideAfter":false,"hideOn":false,"hideOthers":false,"position":{"tooltip":"topright","target":"bottommiddle"},"inline":false,"offset":{"x":0,"y":0},"onHide":false,"padding":true,"radius":true,"shadow":true,"showOn":{"element":"click"},"size":"medium","spinner":true,"stem":true,"target":"element","voila":true,"skin":"light","hideOnClickOutside":true}"
  • Because this is a component, once it is hidden it is disposed so I need to be able to remove the Tipped instance correctly and safely in this case
  • Just a follow up, I have a temporary workaround for this error (although I really don't like it :)). If I called Tipped.disable(elementName) instead of Tipped.remove(elementName) I don't get the stacking issue and I don't get the console error. One question I have is that if I disable the element and then the component is disposed, i.e. the target content is removed from the DOM, are Tipped instances stored in memory somewhere?
  • edited January 2016
    Is your problem fixed if you replace detach with this?:
    detach: function() {
    if (this.options.detach && !this.is('detached')) {
    if (this._tooltip) this._tooltip.detach();
    this.is('detached', true);
    }
    },
    After Tipped.remove() is called everything is cleaned up from memory, a bug in detaching would prevent that from happening though.

    You mentioned nesting, I guess that could be causing this. I'll need to build some tests to see if I can replicate this to make sure it's properly fixed.
  • I replaced detach with your updated method and it doesn't appear to be throwing errors anyway which is great. Thanks for your help on this!
  • Thanks, I've put this fix into 4.5.4
Sign In or Register to comment.