String is not a function when loading backbone render function - backbone.js

The below is a piece of code implemented on backbone.
new staffListViewN().render(qualifiedStaff,this.id);
I am getting error like
"String is not a function"
below is the implementation of the above render function.
staffListViewN = Backbone.View.extend({
el:'#staffs-list',
render:function(stafflistParam,id)
{
var stafflist = stafflistParam;
var ref = this;
if(validate.variable(stafflist))
{
agentList = {agentList:stafflist};
ref.$el.html(staffListTemplate);
}
}
});

Related

protractor --page objects ,getting error Cannot read property 'click' of undefined. How to resolve this error?

trying to access menu of an angular application from spec.js using page object menu.js but when running the protractor error is coming up. Failed: Cannot read property 'click' of undefined
spec.js
var loginpage = require('./login');
var Menu = require('./menu');
describe('todo', function() {
it('activity', function() {
var question = new loginpage();
var menu = new Menu();
browser.sleep(10000);
menu.dropdown('Inquiry').click();
});
});
PAGE OBJECT FILE menu.js
var MenuPage = function() {
this.dropdown = function(dropdownName) {
var openDropdown = function() {
element(by.css('.nav'))
.element(by.css('[title=dropdownName]'))
.click();
};
return {
option: function(optionName) {
openDropdown();
return element(by.css('.dropdown.open'))
.element(by.linkText(optionName));
}
}
};
};
module.exports = MenuPage;
Wow, you have old style in your tests. It's much more easier to use new features of JS.
However, you return object. Instead of it return element. You can return function that will return element regarding to your code style:
return function(optionName) {
openDropdown();
return element(by.css('.dropdown.open'))
.element(by.linkText(optionName));
}

Angular 1.x and AG-Grid Components

I'm trying to upgrade our app from a really old version to the latest (v16). Since they have deprecated the old way of cell and header renders I'm trying to wrap my head around using scope and Angular compilation.
The ag-grid documentation states: You will then need to manage creating and destroying child scopes yourself inside the init() and destroy() methods.
angularCompileRows, angularCompileFilters and angularCompileHeaders are not supported within Components.
I tried to create a cell render like this:
function MyCellRenderer() {
}
MyCellRenderer.prototype.init = function (params) {
$scope.myMessage = 'Hi Scott';
var compiled = $compile('<p ng-bind="myMessage"></p>')($scope);
this.eGui = document.createElement('span');
this.eGui.innerHTML = compiled.html();
};
MyCellRenderer.prototype.getGui = function () {
return this.eGui;
};
However this doesn't work. Any thoughts?
I was able to get this to work, but I don't like that I need to wrap around a $timeout. I had to do this because a digest was already in progress:
function MyCellRendererSimple() {
}
MyCellRendererSimple.prototype.init = function (params) {
console.log('init Called');
this.eGui = document.createElement('span');
};
MyCellRendererSimple.prototype.getGui = function () {
var self = this;
$timeout(function() {
var compiled = $compile('<nice-checkbox checkbox-id="checkbox-2" ng-model="checkboxModal1"></nice-checkbox>')($scope);
$scope.$digest();
self.eGui.appendChild(compiled[0]);
});
return self.eGui;
};

how to convert a string data to JSX?

i want to fetch a remote data, and this data is JSX template. i want to use this data to dynamic render html.
my code
var Input = require('./components/input.jsx')
var Button = require('./components/Button.jsx')
var Panel = require('./components/panel.jsx')
var Container = require('./components/container.jsx')
var Styles = require('./components/styles.jsx')
var Style = require('./components/style.jsx')
var LoadData = require('./lib/LoadData');
LoadData.load('life_nearby_food', function(string){
// string may be link "<Container><Layout orientation="vertical" width="fill" height="wrap">...</Layout></Container>" etc
var app = React.createClass({
render: function() {
return string;
}
});
});

Protractor: classes inheritance

I have 3-levels of inheriting classes:
First class inherit ElementArrayFinder, Second class inherit first class. This is my code:
1-st class:
var util = require('util');
var ElementArrayFinder = require('C:/Users/Lilia.Sapurina/AppData/Roaming/npm/node_modules/protractor/lib/element').ElementArrayFinder;
var psComponent = function() {};
util.inherits(psComponent, ElementArrayFinder);
module.exports = psComponent;
2-nd class:
var util = require('util');
var psComponent = require('../lib/psComponent');
var psDateTimePicker = function() {};
util.inherits(psDateTimePicker, psComponent);
psDateTimePicker.prototype.getField = function() {
return element(by.xpath('//div[1]/table/tbody/tr[2]/td[1]/div/input'));
};
psDateTimePicker.prototype.getButton = function() {
return element(by.css('td > a.b-button.b-button_only_icon'));
};
exports.psDateTimePicker = new psDateTimePicker();
I can use it in my code in this way:
fdescribe('lala', function () {
var psDateTimePicker = require('../lib/psDateTimePicker').psDateTimePicker;
beforeEach(function(){
browser.get('ng-components/examples/ps-date-time-picker.html');
});
it('test', function () {
expect(psDateTimePicker.getField().getAttribute("value")).toEqual(6);
});
});
But I want to make global interface and make code construction looks like:
fdescribe('lala', function () {
var psComponents = require('../lib/psComponent');
beforeEach(function(){
browser.get('ng-components/examples/ps-date-time-picker.html');
});
it('test', function () {
expect(psComponents.psDateTimePicker.getField().getAttribute("value")).toEqual(6);
});
});
Does anybody know how I can organize it? I tried to use getInstanceOf(), but its not working. Also it isn't very conveniently.
If you want to create a namespace for all your components, you can just create an extra module responsible for that:
// psComponents.js
module.exports = {
psDateTimePicker: require('../lib/psDateTimePicker').psDateTimePicker,
psAnotherComponent: require('../lib/psAnotherComponent').psAnything
};
And use it pretty like the same you want:
var psComponents = require('../lib/psComponents');
expect(psComponents.psDateTimePicker.getField().getAttribute("value")).toEqual(6);
This is much simpler than what you've tried to do - trying to access children from a parent - there is no an easy way to achieve it and usually there is no reason to. Prototypes are just boilerplates to create new independent instances, which are not supposed to be connected to each other. Pretty much the same with prototype inheritance: you just extend that boilerplate, but child and parent instances a gonna remain independent.
Not entirely sure what you're looking for but maybe something along these line...?
var util = require('util');
var ElementArrayFinder = require('C:/Users/Lilia.Sapurina/AppData/Roaming/npm/node_modules/protractor/lib/element').ElementArrayFinder;
var psDateTimePicker = require('../lib/psDateTimePicker').psDateTimePicker;
var PsComponent = function() {};
util.inherits(PsComponent, ElementArrayFinder);
PsComponent.prototype = util;
PsComponent.prototype = psDateTimePicker;
module.exports = new PsComponent();
Then...
describe('lala', function () {
var psComponents = require('../lib/psComponents');
beforeEach(function(){
browser.get('ng-components/examples/ps-date-time-picker.html');
});
it('test', function() {
expect(psComponents.getField().getAttribute("value")).toEqual(6);
});
});

backbone structure / collections / views passing and returning data

So I am putting together a very simple app and have got a bit stuck.
So far I have my router
var AppRouter = Backbone.Router.extend({
routes:{
"":"home"
},
initialize:function () {
// Handle back button throughout the application
$('.back').live('click', function(event) {
window.history.back();
return false;
});
this.firstPage = true;
this.products = new Products();
},
home:function () {
var view = new HomeView({collection:this.products});
// render the view when the collection is loaded
this.products.on("renderCompleted:Products", function() {
//alert("ff");
view.render();
});
// fetch should trigger "reset" when complete
this.products.fetch();
}
my model
var Product=Backbone.Model.extend({
defaults:{
id:"",
name:'',
longName:'',
productID:''
}
});
return Product;
my collection
var Products=Backbone.Collection.extend({
// Book is the model of the collection
model:Product,
fetch:function(){
var self=this;
var tmpItem;
//fetch the data using ajax
var jqxhr = $.getJSON("data/product.json")
.success(function(data, status, xhr) {
$.each(data.data.productTypeList, function(i,item){
tmpItem=new Product({id:item.id,name:item.name,longName:item.longName, productID:i});
self.add(tmpItem);
});
self.trigger("fetchCompleted:Products");
})
}
});
return Products;
and my view
var HomeView = Backbone.View.extend({
template: _.template(homeViewTemplate),
render:function (eventName) {
//$(this.el).html(this.template());
this.$el.empty();
//compile template using the data fetched by collection
this.$el.append(this.template({data:this.collection.toJSON()}));
console.log("test" + this.collection.get('data'));
return this;
}
the homeViewTemplate call has this HTML
<ul >
<% for (var i = 0; i < data.length; i++) { %>
<% var item = data[i]; %>
<li>
<%= item.longName %>
</li>
<% } %>
</ul>
you can see from the router that on init this.Products is created of the collection
then when home is called it runs the view.
I dont think anything is passed from the collection to the view though and I am not sure how this is done? Is my collection setup wrong? - do I have to call fetch and pass that to the view?
Any help is appreciated
thanks
do I have to call fetch and pass that to the view?
You have to call fetch, and have its success callback trigger view.render. You could do that using the success option of the JQuery call; or using the reset event, which collection.fetch normally calls. I'd suggest putting collection.reset inside your custom fetch:
// get the data an an array of models
var models = data.data.productTypeList.map(function(item) {
return new Product({id:item.id,name:item.name,longName:item.longName, productID:i});
});
// populate the collection
self.reset(models);
And then in the "home" route, call fetch and then call render on the callback:
home:function () {
var view = new HomeView({collection:this.products});
// render the view when the collection is loaded
this.products.on("reset", function() {
view.render();
});
// fetch should trigger "reset" when complete
this.products.fetch();
}

Resources