Object has no method 'call' when setting Backbone Model from Trigger - javascript

So, I just spent about 3 hours trying to debug this nasty thing and I'm at wits end.
What I'm trying to do is fairly simple. I'm working with a search query (string) and trying to set a global model with its attributes. However, when I'm moving to a different view, I want the model to clear out these attributes, or of course when they enter a new search query, have the event fire again. I'm trying to use the Backbone Marionette Wreqr / Event Aggregator to manage the events here.
I don't know if it's because I'm using requirejs, or not scoping things correctly, but I'm hitting this very confusing error:
Uncaught TypeError: Object #<Object> has no method 'call' backbone.amd.min.js:1
f backbone.amd.min.js:1
e.Events.trigger backbone.amd.min.js:1
i.extend.set backbone.amd.min.js:1
(anonymous function) app.js:42
f backbone.amd.min.js:1
e.Events.trigger backbone.amd.min.js:1
Application.searchRoute app.js:81
(anonymous function) backbone.amd.min.js:1
(anonymous function) backbone.amd.min.js:1
w.some.w.any underscore.amd.min.js:1
i.extend.loadUrl backbone.amd.min.js:1
i.extend.navigate backbone.amd.min.js:1
i.extend.navigate backbone.amd.min.js:1
SidebarLayout.search sidebar.js:177
(anonymous function) sidebar.js:3
x.event.dispatch jquery.min.js:5
y.handle
And here's some of my application code (my main controller). As you can see, I'm trying to set up the app.searchResult model with these other parameters from the searchRoute method.
What's so bizarre is that it works the first time the page loads, but when I attempt to use router navigate or do anything but refresh the page, it fails.
I tried using #searchResult instead, tried adding a , # after my trigger call, and all sorts of other things. What's stranger is that inside that scope, app.searchResult is available to me. And as soon as I remove the set call from there, the error doesn't happen anymore, so I'm thinking it must be that?
define [
'backbone.marionette',
'global/layouts/home',
'global/layouts/layout',
'search/models/search-results',
'search/collections/panels',
'global/collections/categories',
'global/collections/stores',
'global/collections/searchResults',
'search/views/panels',
'apps/router'
], (Marionette, homeLayout, subpageLayout, SearchResultModel, PanelsCollection, CategoriesCollection, StoresCollection, SearchResultsCollection, PanelsView, Router) ->
class Application extends Backbone.Marionette.Application
onInitializeAfter: =>
# Main Region
#addRegions
mainRegion: '#app'
# AppRouter
#router = new Router controller: #
# Request Response / Vent
#reqRes()
#appVent()
# Global Search Result Model
#searchResult = new SearchResultModel()
Backbone.history.start
pushState: false
root: ""
searchRoute: (query, params) ->
params = $.extend params, text: query
#vent.trigger "search:setParams", params
#subpageLayout = new subpageLayout()
#mainRegion.show #subpageLayout
appVent: ->
#vent.on "search:setParams", (params) ->
app.searchResult.set("params", params)
#vent.on "sidebar:reset", ->
app.searchResult.set("params", null)
I can send more code if you like, but the idea is to use a custom trigger like sidebar:reset to clear out these parameters. I'm also listening to some model events (all of that stuff is working great from within the context of the view and when I don't mess with the event aggregator).
Thanks in advance for your help. You have no idea how many hours I just spent on this!

Related

Adding an IndexedLineSet in X3Dom

When working with X3D via X3Dom, sometimes I'd like to add objects dynamically. As an example, I might have a function like the following to add a line:
function add_line(lineString) {
var lineString = lineString || random_line();
var orbit = $("<shape></shape>");
scene.append(orbit);
var indexedLineSet = $("<IndexedLineSet></IndexedLineSet>");
orbit.append(indexedLineSet).attr('coordIndex', '0 1');
var coordinate = $("<coordinate></coordinate>");
coordinate.attr('point', lineString);
indexedLineSet.append(coordinate)
}
In this code, scene is an existing X3D scene, random_line is a function that generates a string defining a random line, and I'm manipulating the scene with JQuery. When calling the function as the page loads, it works just fine. When calling the function in response to a button push, however, the line doesn't appear, though it is added to the scene.
Notes:
The problem appears to depend on the type of object I try to add. Spheres can be added without any problem.
According to Firefox's inspector, the IndexedLineScene appears to be added to the scene correctly; it just doesn't appear in the image.
If you open up your developer console you can find:
x3dom.js:3014 Uncaught TypeError: Cannot read property 'getPoints' of null_
buildGeometry # x3dom.js:3014
nodeChanged # x3dom.js:3046
x3dom.NodeNameSpace.setupTree # x3dom.js:2744
onNodeInserted # x3dom.js:1100
(anonymous function) # jquery-1.12.4.min.js:3
Ha # jquery-1.12.4.min.js:3
append # jquery-1.12.4.min.js:3
add_line # IndexedLineSet-Test.html:76
(anonymous function) # IndexedLineSet-Test.html:90
dispatch # jquery-1.12.4.min.js:3
r.handle # jquery-1.12.4.min.js:3
After investigation line 76 of your original code, you will find that you have to change the order of adding the points and adding the indices:
var indexedLineSet = $("<IndexedLineSet></IndexedLineSet>");
var coordinate = $("<coordinate></coordinate>");
coordinate.attr('point', lineString);
indexedLineSet.append(coordinate);
orbit.append(indexedLineSet).attr('coordIndex', '0 1');
It works well for you on the initial load, because you construct the x3d before X3DOM is ready, check when this call appears (after your calls to add_line have been finished):
x3dom.runtime.ready = function() {
console.log('ready');
};
This means that all the events and listeners are not setup yet. But later when you click that button X3DOM has been initialized completely. Thus it can listen to all events and fires the onNodeInserted event right after you append orbit to scene. Another solution would be to have this call right at the end of your function:
Construct the 3D object completely
Add the object (orbit) to the scene.

Why is this findOne in a template event causing a call stack size error?

I am trying to have a forEach in SpaceBars that shows some buttons that can be pressed for each thing in an array. However, when I press the button, it gives me this error:
Uncaught RangeError: Maximum call stack size exceeded underscore.js:1025
_.(anonymous function) # underscore.js:1025
EJSON.clone # ejson.js:475
(anonymous function) # ejson.js:494
.each..forEach # underscore.js:113
EJSON.clone # ejson.js:493
... same stuff for a while ...
.each..forEach # underscore.js:113
EJSON.clone # ejson.js:493
(anonymous function) # ejson.js:494
.each..forEach # underscore.js:113
EJSON.clone # ejson.js:493
This is the findOne that's causing the error:
"click .acceptFriend": function(requester){
currentUserId = Meteor.userId();
requesterUsername = requester;
requesterId = friendRequests.findOne({$and:[{target:currentUserId}, {requester:requesterUsername}]})._id;
Meteor.call("acceptRequest", requesterId, requester);
}
I know it's the friendRequests.findOne because I have done console logs on each line, and that is the line that breaks it. I have tried several different variations, but it seems that any type of find on the friendRequests collection in that context breaks it. The relevant part of the template is this:
{{#each getRequests}}
{{requester}} <button class='acceptFriend'>accept</button>
{{/each}}
Why is this error happening and how can I solve it?
If we look at the documentation about events:
The handler function receives two arguments: event, an object with
information about the event, and template, a template instance for the
template where the handler is defined. The handler also receives some
additional context data in this, depending on the context of the
current element handling the event. In a template, an element's
context is the data context where that element occurs, which is set by
block helpers such as #with and #each.
To sum up: events in Meteor do not receive their data context as an argument: they receive the event object and the template instance where the event occured. The data context is stored in this.
So what you should probably do is the following:
"click .acceptFriend": function(event, template){
currentUserId = Meteor.userId();
requesterUsername = this.requester;
requesterId = friendRequests.findOne({$and:[{target:currentUserId}, {requester:requesterUsername}]})._id;
Meteor.call("acceptRequest", requesterId, requesterUsername);
}

Ember.js: How to track down deferred action runtime errors?

I occasionally get the following runtime error.
Assertion failed: Error while loading route: TypeError: Cannot call method 'get' of undefined ember.js?body=1:3226
(anonymous function) ember.js?body=1:3226
defaultActionHandlers.error ember.js?body=1:32032
triggerEvent ember.js?body=1:31884
trigger ember.js?body=1:30910
Transition.trigger ember.js?body=1:30131
handleError ember.js?body=1:31244
invokeCallback ember.js?body=1:8377
(anonymous function) ember.js?body=1:8431
EventTarget.trigger ember.js?body=1:8200
(anonymous function) ember.js?body=1:8502
DeferredActionQueues.flush ember.js?body=1:5674
Backburner.end ember.js?body=1:5765
Backburner.run ember.js?body=1:5804
executeTimers ember.js?body=1:6056
(anonymous function) ember.js?body=1:5914
The problem is that the entire call stack is ember code. But the error must be caused by my code.
What is a generic approach to determine the original code that is causing the problem?
Set your debugger to stop on all exceptions, then walk up the stack trace and find out what code of yours is firing it.
This particular error looks like you were transitioning to another route and it blew up. There are only a few things (major understatement) that happen during the transition, I'll point out the biggins that would break the transition, they are all located on the route.
overridden model hook
overridden setupController hook
overridden serialize hook
You'll want to look through your code and add either add some validation that an item exists before you call get on it, or switch to using Ember.get(obj, property), but that just pushes off your exception until later.
I see this error a lot in the setupController and serialize hook.
serialize: function(model){
// good spot to fail
return { custom_id: model.get('some_id') };
}
setupController: function(controller, model){
// good spot to fail
var something = model.get('something');
}
These particular areas speak to a bigger issue, your model hook (or transitionTo/transitionToRoute code) is passing a null/empty model.

Ember.js - Cannot perform operations on a Metamorph that is not in the DOM

I am using Ember.js version 1.0.0-rc.3 and recently started seeing:
Uncaught Error: Cannot perform operations on a Metamorph that is not in the DOM. lib- dev.js:28254
Metamorph.checkRemoved lib-dev.js:28254
Metamorph.html lib-dev.js:28224
SimpleHandlebarsView.update lib-dev.js:29167
(anonymous function) lib-dev.js:14424
Ember.handleErrors lib-dev.js:10331
invoke lib-dev.js:14422
invokeOnceTimer lib-dev.js:14875
(anonymous function) lib-dev.js:14424
Ember.handleErrors lib-dev.js:10331
invoke lib-dev.js:14422
iter lib-dev.js:14492
RunLoop.flush lib-dev.js:14546
RunLoop.end lib-dev.js:14451
tryable lib-dev.js:14652
Ember.tryFinally lib-dev.js:11119
Ember.run.end lib-dev.js:14655
autorun
I have no idea where this is coming from, and how to start tracking it down. Any ideas?
I think I tracked it down. It was because we were setting .html() with jQuery and blowing away:
<script id="metamorph-XXX-start" type="text/x-placeholder"></script>
Tags.

Polling change on rails with railscasts revised

I am trying to follow polling for change but i get the following error
Uncaught TypeError: Object [object global] has no method CommentPoller
Here the code in my comment.js.coffee file
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
#CommentPoller ->
poll: ->
setTimeout #request, 5000
request: ->
$.get($('#comments').data('url'))
jQuery ->
if $('#comments').length > 0
CommentPoller.poll()
What i am doing wrong?
Thank you
Try changing the first line
from
#CommentPoller ->
to
CommentPoller =

Categories

Resources