Marionette.js Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node' - node.js

Here is my LayoutView:
define(["marionette", "lodash", "text!fonts/template.html",
"fonts/controls/view", "fonts/products/view"],
function(Marionette, _, templateHTML, ControlsView, ProductsView) {
'use strict';
var FontsView = Marionette.LayoutView.extend({
regions: {
controls: '#controls',
products: '#products-list'
},
template: _.template(templateHTML),
onRender: function() {
this.getRegion('controls').show(new ControlsView());
this.getRegion('products').show(new ProductsView());
}
});
return FontsView;
});
Here is my ProductsView:
define(["marionette", "lodash", "text!fonts/products/template.html",
'fonts/products/item-view', 'fonts/products/collection'],
function(Marionette, _, templateHTML, ProductItemView, ProductsCollection) {
'use strict';
var ProductsView = Marionette.CompositeView.extend({
el: '.items',
template: _.template(templateHTML),
childView: ProductItemView,
initialize: function() {
this.collection = new ProductsCollection();
}
});
return ProductsView;
});
The error (from the console), is occurring on the this.getRegion('products').show(new ProductsView());

Remove el: '.items', from the ProductsView and it will work. Marionette is already managing the region and gets confused when el is specified on a child view.

Related

Require not working when used in jupyter/ipython notebook

When I write the following code in jupyter opened from my system, it is working, but when I open it from another system it is not. The problem is with require(it is not running). I have put some consoles to see where it is stopping and it is running till console.log(require.s.contexts._.defined). I have checked the modules with this console and angular seems to be missing in this. Thanks in advance.
%%javascript
require.config({
paths: {
velocity: "https://cdn.jsdelivr.net/velocity/1.2.3/velocity.min",
interact: "https://cdn.jsdelivr.net/interact.js/1.2.6/interact.min",
angular: "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min"
},
shim: {
'angular': {
exports: 'angular'
}
}
});
function start_application(data) {
// console.log("data ready")
console.log(require.s.contexts._.defined)
require(['angular', 'jquery'], function(angular,$) {
console.log("require running")
$.ajax({url: "http://localhost:8889/tree/Jupyter_Angular/DQAForm.html",
success: function(result) {
// console.log("SUCCESS")
// console.log(result);
$("#DQAFormContainer").html(result)
var el = document.getElementById("dqaBrickContent");
if(angular.element(el).injector()){
angular.element(el).injector().get('$rootScope').$destroy()
}
var dqaBrick = angular.module('dqaBrick', []);
dqaBrick.controller('dqaBrickCtrl', ['$scope', function ($scope) {
$scope.myVariable = 'Starting new DQA Brick';
console.log($scope.myVariable);
$scope.showPanel = 1;
$scope.openPanel = function (panelNum) {
$scope.showPanel = panelNum;
// console.log(panelNum);
}
}]);
angular.element(document).ready(function() {
angular.bootstrap(el, ['dqaBrick']);
});
}
});
})
}
var callbacks = {
iopub : {
output : start_application
}
}
var kernel = IPython.notebook.kernel
kernel.execute('print("This is the starting")', callbacks)

socket.io-client + react, where to connect to the server?

I'm writing a very simple Nodejs app. I use React + Socket.io.
There's a root element which immediately renders another react component (you may wonder why I have this root element. The reason is that I want to be able to mount one of the two components after receiving a message from server, but for the start I render a preselected component).
In this root component , I define a socket in componentDidMount . Now the problem is that I want to pass this socket to all of the children (so they can listen and communicate with the server messages.) But if I connect to the server in componentDidMount of the root, during the rendering there is no socket as it's not connected yet and null will be passed to the child components.
'use strict';
var React = require('react');
var ioClient = require('socket.io-client');
var UsersList = require('./usersList');
var Game = require('./game');
var socket;
var Snake = React.createClass({
displayName: 'Snake',
propTypes: {},
getDefaultProps: function() {
return {};
},
mixins: [],
getInitialState: function() {
return ({
usersList: true,
game: false
});
},
componentWillMount: function() {
},
componentWillUnmount: function() {
this.socket.close();
},
componentDidMount: function() {
socket = ioClient.connect(); // this happens after render
},
render: function() {
var result = null;
if (this.state.usersList) {
result = <UsersList socket={socket}/> // therefore this one is passed as null
} else { //game : true
result = <Game socket={socket}/>
}
return (<div>
{result}
</div>)
}
});
module.exports = Snake;
'use strict';
var React = require('react');
var UsersList = React.createClass({
displayName: 'UsersList',
propTypes: {},
getDefaultProps: function() {
return {};
},
mixins: [],
getInitialState: function() {
return ({
usersList:[]
});
},
componentWillReceiveProps: function(){
},
componentWillMount: function() {
},
componentWillUnmount: function() {
},
componentDidMount: function(){
var socket = this.props.socket; // this one was passed into the component as null
socket.on('usersList', function(data){ // so this one returns an error
this.setState({
usersList: data.usersList
});
});
},
render: function() {
var users = [];
for (var i = 0 ; i < this.state.usersList.length ; i++){
users.push(<span>{this.state.usersList[i]}</span>);
}
return(<div>{users}</div>);
}
});
module.exports = UsersList;
So , now you may ask why I don't put io.connect() in componentWillMount or at the top of the file. Well , it doesn't work ! it returns this error : Cannot find property "protocol" ....
I cannot put it in render , componentWillMount , top of the file ...
Any idea on how to do this ?
You could continue to connect in componentDidMount. It will not be immediately available to the component's children, but then you could do something like this in the children:
componentDidUpdate(prevProps, prevState) {
if ( this.props.socket ) {
// do your connection logic here
}
}
This will ensure that the children immediately connect when the socket is first connected and available to them. Inside the if statement you could also verify that this.props.socket is not equal to prevProps.socket to prevent a redundant connection attempt.

problems with databinding with angularjs

Hy folks, I got a problem with databinding. I tried since ages to figure out why my few has no access to my global.user provided by a service.
Could somebody figure out whats happening. Thank in advance. best regards Thomas
profile.html
<section data-ng-controller="MyprofileController">
<h1>{{global.current_User()}}</h1>
</section>
myprofile.js
'use strict';
angular.module('mean.system').controller('MyprofileController', ['$scope', 'Global', function ($scope, Global) {
$scope.global = Global;
$scope.test = 'testcase';}]);
service
'use strict';
//Global service for global variables
angular.module('mean.system').factory('Global', [
function() {
var current_user = window.user;
return {
current_User: function() {
return current_user;
},
isloggedIn: function() {
return !!current_user;
}
};
}
]);
thanks a lot for your help.
Just found out that firefox does print an error message!
Error: [ng:areq] Argument 'MyprofileController' is not a function, got undefined
http://errors.angularjs.org/1.2.11/ng/areq?
p0=MyprofileController&p1=not%20a%20function%2C%20got%20undefined
minErr/<#http://localhost:3000/lib/angular/angular.js:78
assertArg#http://localhost:3000/lib/angular/angular.js:1363
assertArgFn#http://localhost:3000/lib/angular/angular.js:1374
#http://localhost:3000/lib/angular/angular.js:6774
nodeLinkFn/<#http://localhost:3000/lib/angular/angular.js:6186
forEach#http://localhost:3000/lib/angular/angular.js:310
nodeLinkFn#http://localhost:3000/lib/angular/angular.js:6173
compositeLinkFn#http://localhost:3000/lib/angular/angular.js:5637
publicLinkFn#http://localhost:3000/lib/angular/angular.js:5542
ngViewFillContentFactory/<.link#http://localhost:3000/lib/angular-route/angular-
route.js:915
nodeLinkFn#http://localhost:3000/lib/angular/angular.js:6228
compositeLinkFn#http://localhost:3000/lib/angular/angular.js:5637
publicLinkFn#http://localhost:3000/lib/angular/angular.js:5542
boundTranscludeFn#http://localhost:3000/lib/angular/angular.js:5656
controllersBoundTransclude#http://localhost:3000/lib/angular/angular.js:6248
update#http://localhost:3000/lib/angular-route/angular-route.js:865
Scope.prototype.$broadcast#http://localhost:3000/lib/angular/angular.js:12245
updateRoute/<#http://localhost:3000/lib/angular-route/angular-route.js:556
qFactory/defer/deferred.promise.then/wrappedCallback#http:
//localhost:3000/lib/angular/angu lar.js:10949
qFactory/defer/deferred.promise.then/wrappedCallback#http:
//localhost:3000/lib/angular/angu lar.js:10949
qFactory/ref/<.then/<#http://localhost:3000/lib/angular/angular.js:11035
Scope.prototype.$eval#http://localhost:3000/lib/angular/angular.js:11961
Scope.prototype.$digest#http://localhost:3000/lib/angular/angular.js:11787
Scope.prototype.$apply#http://localhost:3000/lib/angular/angular.js:12067
#http://localhost:3000/lib/angular/angular.js:9202
createEventHandler/eventHandler/<#http://localhost:3000/lib/angular/angular.js:2613
forEach#http://localhost:3000/lib/angular/angular.js:310
createEventHandler/eventHandler#http://localhost:3000/lib/angular/angular.js:2612
<section class="ng-scope" data-ng-view="">
It should work, and it does in a Fiddle I've created: http://jsfiddle.net/BernhardW/mLQWs/
window.user = 'John Doe';
angular.module('mean.system', []);
angular.module('mean.system').controller('MyprofileController', function ($scope, Global) {
$scope.global = Global;
$scope.test = 'testcase';
});
angular.module('mean.system').factory('Global', function() {
var current_user = window.user;
return {
current_User: function() {
return current_user;
},
isloggedIn: function() {
return !!current_user;
}
};
});
Are there any errors showing?

backbone.js and express: trouble searching a mongodb collection by field with a query string

I am new to backbone, express, and mongodb.
I am trying to pass a query string to search a mongodb collection by field.
I am doing something wrong. If I comment out the "fetch" from my router, the page is found.
If I try to fetch, then I get a page not found error.
I've tried to isolate where it's breaking, but the backbone architecture is still confusing to me. Thanks in advance. (I'm betting it's a syntax issue in my mongodb call)
kristin
Here is my code.
this URL should return a collection where "type" = 3.
localhost:8888/#content/3
model/models.js:
window.Content = Backbone.Model.extend({
urlRoot: "/content",
idAttribute: "_id"
});
window.ContentCollection = Backbone.Collection.extend({
model: Content,
url: "/content"
});
views/content.js
window.ContentListView = Backbone.View.extend({
initialize: function () {
this.render();
},
render: function () {
//return this;
this.$el.append('<ul class="thumbnails">');
this.collection.each(function(model) {
this.$('.thumbnails').append(new ContentView({model: model}).render().el);
}, this);
return this;
} });
window.ContentView = Backbone.View.extend({
tagName: "li",
initialize: function () {
this.model.bind("change", this.render, this);
this.model.bind("destroy", this.close, this);
},
render: function () {
$(this.el).html(this.template(this.model.toJSON()));
return this;
}
});
views/main.js
var AppRouter = Backbone.Router.extend({
routes: { "content/:type" : "contentType" },
contentType: function(type) {
var contentList = new ContentCollection({type : type});
contentList.fetch({success: function(){
$("#content").empty().append(new ContentListView({collection: contentList}).el);
}});
this.headerView.selectMenuItem('build-menu');
},
utils.loadTemplate([
'ContentView'
], function() {
app = new AppRouter();
Backbone.history.start(); });
contentView.html
name (<% tag won't print here)
routes/modules.js
exports.findContentByType = function(req, res) {
var type = req.params.type;
db.collection('content', function(err, collection) {
collection.find({'type': type.toString()}).toArray(function(err, items) {
res.send(items);
});
});
};
server.js
app.get('/content/:type', module.findContentByType);
I can see a couple of problems here:
this.headerView.selectMenuItem('build-menu'); (in the router) implies you've defined headerView in the router object, but it's not defined.
Similarly, this.template inside ContentView is not defined
When I remove the line in #1, and and define a dummy template in ContentView:
template: _.template("<div> Test: <%= version %> </div>"),
Then the view at least renders -- see here. (This is with dummy data -- I can't confirm that your server is returning valid/expected JSON.)

populating menus from multiple collections

I'm new to backbone.js and express and I have been adapting Christophe Coenraets Wine Cellar REST API example application for my own project.
I am building a form that has several menus needing to be populated from multiple unrelated collections in mongodb.
I am able to populate one menu with one collection, but I have no idea how to get more than one collection to my form View.
Here are the files I am using to populate one menu. How do I expand this to populate two menus?
I suppose I could make a new View for every menu I want to populate - but that seems like overkill.
Can I combine two mongodb find() collections into one object, and list them separately on a page? If so, how?
thanks in advance!
/routes/modules.js contains:
exports.findAllModules = function(req, res) {
db.collection('modules', function(err, collection) {
collection.find().toArray(function(err, items) {
res.send(items);
});
});
};
/server.js contains:
app.get('/modules', module.findAllModules);
/public/js/main.js contains:
routes: {
"modules" : "list" }
...
list: function(page) {
var p = page ? parseInt(page, 10) : 1;
var moduleList = new ModuleCollection();
moduleList.fetch({success: function(){
console.log('in list function');
$("#content").html(new ModuleListView({model: moduleList, page: p}).el);
}});
this.headerView.selectMenuItem('home-menu');
},
...
utils.loadTemplate([
'ModuleListItemView' ], function() {
app = new AppRouter();
Backbone.history.start(); });
/public/models/models.js contains:
window.Module = Backbone.Model.extend({
urlRoot: "/modules",
idAttribute: "_id",
initialize: function () {
this.validators = {};
this.validators.name = function (value) {
return value.length > 0 ? {isValid: true} : {isValid: false, message: "You must enter a name"};
};
validateItem: function (key) {
return (this.validators[key]) ? this.validators[key](this.get(key)) : {isValid: true};
},
validateAll: function () {
var messages = {};
for (var key in this.validators) {
if(this.validators.hasOwnProperty(key)) {
var check = this.validators[key](this.get(key));
if (check.isValid === false) {
messages[key] = check.message;
}
}
}
return _.size(messages) > 0 ? {isValid: false, messages: messages} : {isValid: true};
},
defaults: {
_id: null,
name: ""
} });
window.ModuleCollection = Backbone.Collection.extend({
model: Module,
url: "/modules"
});
/public/js/views/modulelist.js contains:
window.ModuleListView = Backbone.View.extend({
initialize: function () {
this.render();
},
render: function () {
var modules = this.model.models;
$(this.el).html('<ul class="thumbnails"></ul>');
for (var i = 0; i < modules.length; i++) {
$('.thumbnails', this.el).append(new ModuleListItemView({model: modules[i]}).render().el);
}
return this;
} });
window.ModuleListItemView = Backbone.View.extend({
tagName: "li",
initialize: function () {
this.model.bind("change", this.render, this);
this.model.bind("destroy", this.close, this);
},
render: function () {
$(this.el).html(this.template(this.model.toJSON()));
return this;
} });
/public/tpl/ModuleListView.html contains:
Not entirely sure how your code works, but here are a few backbone tips.
If you wanna build a menu from a collection don't pass the collection as a model.
Instead of:
$("#content").html(new ModuleListView({model: moduleList, page: p}).el);
Use:
$("#content").empty().append(new ModuleListView({collection: moduleList, page: p}).el);
Instead of:
render: function () {
var modules = this.model.models;
$(this.el).html('<ul class="thumbnails"></ul>');
for (var i = 0; i < modules.length; i++) {
$('.thumbnails', this.el).append(new ModuleListItemView({model: modules[i]}).render().el);
}
return this;
}
Use:
render: function () {
this.$el.html('<ul class="thumbnails">');
this.collection.each(function(model) {
this.$('.thumbnails').append(new ModuleListItemView({model: model}).render().el);
}, this);
return this;
}
If you have no need in updating or deleting your models, it's enough to add the url path /modules only to the collection, for reading the initial modules.

Resources