Skip to content
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

Blaze: Uncaught Error: Must be attached #213

Closed
hwillson opened this issue Dec 13, 2016 · 20 comments
Closed

Blaze: Uncaught Error: Must be attached #213

hwillson opened this issue Dec 13, 2016 · 20 comments

Comments

@hwillson
Copy link
Contributor

Migrating this over from meteor/meteor#2981.


(originally reported by @mitar)

See example project. When clicking on "Click Me" button, there is an uncaught Error: Must be attached.

Uncaught Error: Must be attached domrange.js:337
DOMRange.containsElement domrange.js:337
(anonymous function) view.js:741
(anonymous function) events.js:47
jQuery.event.dispatch jquery.js:4624
elemData.handle jquery.js:4292
@bastiW
Copy link

bastiW commented Jan 2, 2017

is there any workaround for this?

@mitar
Copy link
Contributor

mitar commented Jan 2, 2017

Yes, see discussion here.

@aadamsx
Copy link

aadamsx commented Jan 10, 2017

Nice, I just ran into this for the first time today!

@rtcwp07
Copy link

rtcwp07 commented May 5, 2018

I'm probably the last person still using Blaze, but for posterity I will add here that I encountered this error when I was using jQuery to get a field value for a method call, and solved it by making sure that I used the template.$ jQuery call instead.

@dariovillalta
Copy link

@rtcwp07 cheers man, could you please elaborate what you mean with "the template.$ jQuery call"? Thanks!

@dr-dimitru
Copy link
Contributor

Hello @dariovillalta ,

When you have an event handler the first argument is an event and second is instance of the template, so instead of using global $, you should use instance of jquery tied to the current template scope, like:

'click .my-button'(event, template) {
   template.$('my-input').val()
}

@dariovillalta
Copy link

@dr-dimitru nice explaining, thank you so much!

@snajjar
Copy link

snajjar commented Jul 23, 2020

No update after 2 years? This keeps happening a lot (I use external libraries that are based on jquery)...

@filipenevola
Copy link
Collaborator

I'm closing this issue because it's too old.

If you think this issue is still relevant please open a new one.

Why? We need to pay attention to all the open items so we should keep opened only items where people are involved.

@lynchem
Copy link

lynchem commented Dec 1, 2021

I think this is worth reopening @filipenevola as it's still happening a LOT and it would be a shame to lose all the history. It's already been evicted once.

I don't see anything relating to jquery in the callstack for our project. The two most common call stacks I see are as follows:

Error: Must be attached
at meteor://💻app/packages/blaze/domrange.js:191:10
at firstNode (meteor://💻app/packages/blaze/template.js:171:38)
at _currentTemplateInstanceFunc (meteor://💻app/packages/blaze/template.js:559:16)
our code
at apply (meteor://💻app/imports/startup/client/blaze-exceptions.js:13:21)
at apply (meteor://💻app/packages/blaze/exceptions.js:51:15)
at apply (meteor://💻app/imports/startup/client/blaze-exceptions.js:29:58)
at func (meteor://💻app/packages/blaze/template.js:490:13)
at _withTemplateInstanceFunc (meteor://💻app/imports/startup/client/blaze-exceptions.js:28:30)
at apply (meteor://💻app/packages/spacebars.js:172:17)

Error: Must be attached
at meteor://💻app/packages/blaze/domrange.js:337:10
at containsElement (meteor://💻app/packages/blaze/view.js:890:24)
at apply (meteor://💻app/packages/blaze/events.js:47:23)
at apply (meteor://💻app/packages/modules.js:30617:26)
at apply (meteor://💻app/packages/modules.js:30429:27)

@distalx
Copy link
Contributor

distalx commented Jan 16, 2022

I also recently saw this in my project.
For me workaround was to renaming few of the selectors.

domrange.js:337 Uncaught Error: Must be attached
    at Blaze._DOMRange.DOMRange.containsElement (domrange.js:337:11)
    at Blaze._DOMRange.<anonymous> (view.js:891:25)
    at HTMLButtonElement.<anonymous> (events.js:49:24)
    at HTMLDivElement.dispatch (modules.js?hash=5a94ac1782b4de33da07a5edf5fbaede26f5d256:20544:27)
    at HTMLDivElement.elemData.handle (modules.js?hash=5a94ac1782b4de33da07a5edf5fbaede26f5d256:20348:28)

@dr-dimitru
Copy link
Contributor

@distalx can you give an example of the selector you have renamed?

@distalx
Copy link
Contributor

distalx commented Jan 17, 2022

@dr-dimitru Something like primary-action to primary_action. !!

@lynchem
Copy link

lynchem commented Jan 18, 2022

So @distalx , have you managed to get rid of this completely by renaming the button class or id in question.
So if this works does that mean there's some special treatment of hyphens in the code at some point? Seems odd.

Our callstack is so vague I can't pin it down a particular selector to try this out but a huge majority of our ids and classnames have hyphens.

@distalx
Copy link
Contributor

distalx commented Jan 23, 2022

@lynchem, it also seem odd to me. So I've put-together a reproduction for this issue.

https://github.com/distalx/meteor-blaze-issue-213

I believe this error occurs when a parent and a child template both using a same selector-name.

@jankapunkt
Copy link
Collaborator

Maybe related PR: #366

@harryadel
Copy link
Contributor

harryadel commented Jun 9, 2022

So, I've dug deeper into this bug. If both the parent template and child template contain an event handler that triggers on an element that exists in both templates, it seems only natural for it to trigger twice. It triggers in the child component first then once again the parent.

In the case of @distalx example repo, we get Uncaught Error: Must be attached because the event handler destroys the whole view via FlowRouter.go('/') in the child template first so when it triggers again in the parent component it cannot find the HTML/view that's accompanied to it although the event is already triggered!

<template name="parent_template">

  {{!-- The below button renders for specific case --}}
  {{!-- that logic is not important for this reproduction --}}
  <button type="button" class="go-back" name="button" hidden>
    Go back
  </button>
  {{> Template.dynamic template=child_template}}
</template>

Template.parent_template.events({
  'click .go-back'(event, instance) {
    console.log("PARENT TEMPLATE")
    event.preventDefault()
    history.back()
  },
})  	
<template name="child_template">
  <button type="button" class="go-back" name="button">
    Go back
  </button>
</template>


Template.child_template.events({
  'click .go-back'(event) {
    console.log("CHILD TEMPLATE")
    event.preventDefault();
    FlowRouter.go('/')
  }
});	

I'm kind of confused as to how we can "solve" this, because the error is kind of right. You're double-triggering an event that destroys the view so of course it's gonna error in the second time.

We can place a check here to detect this (regardless of how we do it) and exit the process but I'm unsure whether this is the best route because like I said it's not a bug per se. What if this is purposeful? A developer wants to double trigger an event on both the parent and child?? It's pretty weird. I really need your opinion guys.

We may also modify this error so it's more telling of what's going on like event "click .go-back" on "parent_template" triggered but no attached view is found., so developers can tell which event/template caused this error and can modify it.

Side note, but I've contacted @jankapunkt and once we fix this issue we can release 2.6.1.

@dr-dimitru
Copy link
Contributor

We may also modify this error so it's more telling of what's going on like event "click .go-back" on "parent_template" triggered but no attached view is found., so developers can tell which event/template caused this error and can modify it.

Sounds like the most appropriate solution

@harryadel
Copy link
Contributor

harryadel commented Jun 14, 2022

Thank you Dimitry for chiming in. That's one vote down for editing the error message. I need more votes to decide on this.
cc @StorytellerCZ @distalx @jankapunkt @lynchem

@lynchem
Copy link

lynchem commented Jun 14, 2022

Oh wow, great work @distalx & @harryadel for debugging that 👏🏻
Yes, I think that's the best course of action. Knowing the selector would let us track that down in our code and fix things 👍🏻

I think this coupled with what @jankapunkt has done in his PR will allow us to completely eliminate all the Must be Attached warnings 🥳

harryadel added a commit to harryadel/blaze that referenced this issue Jun 18, 2022
Now it outputs a more descriptive version: `${event} event triggerd with ${selector} on ${templateName} but associated view is not be found.
    Make sure the event doesn't destroy the view.`
Fixes meteor#213
jankapunkt added a commit that referenced this issue Jun 22, 2022
…fix #213

Merge pull request #376 from harryadel/view-must-be-attached-error
Thanks to @harryadel
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests