I'm trying to build a version of the todo app using Durandal (including Knockout + RequireJS) from a TodoMVC template. I realize that a todo app doesn't really show off the features of Durandal, but I'm on the learning path and figured it would be a good first project.
Anyway, in the process I've stumbled upon an error that I'm unable to solve (see below).
Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.")
I've also attached an image that shows these in the console.
You can find the source code at https://github.com/robksawyer/durandal-todo. The todo viewmodel is located at https://github.com/robksawyer/durandal-todo/blob/master/viewmodels/todos.js.
Update: Most of the Knockout code is borrowed from the Knockout+Require TodoMVC project at https://github.com/tastejs/todomvc/tree/gh-pages/labs/dependency-examples/knockoutjs_require/
Thanks for your time.
I think you're misreading the console.
For example, "allCompleted" is a property on your view model, which is declared as a dependent observable (i.e. a "computed"):
// writeable computed observable to handle marking all complete/incomplete
self.allCompleted = ko.computed({
// -- trimmed --
});
What you're seeing in the console isn't the Cannot write a value error; it's the debug output for a computed property - i.e. its function definition. For reference, here's the function definition of a dependent observable straight from the knockout (2.2.1) source:
function dependentObservable() {
if (arguments.length > 0) {
if (typeof writeFunction === "function") {
// Writing a value
writeFunction.apply(evaluatorFunctionTarget, arguments);
} else {
throw new Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");
}
return this; // Permits chained assignments
} else {
// Reading the value
if (!_hasBeenEvaluated)
evaluateImmediate();
ko.dependencyDetection.registerDependency(dependentObservable);
return _latestValue;
}
}
What you're seeing in your console is the minified version of this code.
If you want to see the value that's returned by the property you'd have to invoke it.
Related
<full-calendar #unitCalendar [editable]='true' [defaultView]="calendarView" [defaultDate]="unit.start_date*1000" [plugins]="calendarPlugins" [header]="calendarHeader" (eventClick)="viewEventDetails($event)" (eventDrop)='updateDate($event)' (dateClick)="handleDateClick($event)" [eventSources]="calendarEventSource"></full-calendar>
I have tried adding eventAllow as a callback and define a method inside the ts file but the method is never called as if the event is never fired.
I resolved this my self after a frustrating time. The answer is to create a property/variable in the js/ts file titled eventAllow and set the variable to a function with a response type of boolean.
eventAllow = function (dropInfo, draggedEvent) {
if(draggedEvent.extendedProps.calendarEvent.id !== null) {
return true;
}
return false;
}
and read the property/variable in the HTML file like below.
<full-calendar
#unitCalendar
[editable]='true'
[defaultView]="calendarView"
[defaultDate]="unit.start_date*1000"
[plugins]="calendarPlugins"
[header]="calendarHeader"
(eventClick)="viewEventDetails($event)"
(eventDrop)='eventDropped($event)' (eventResize)='eventResized($event)'
[eventAllow]='eventAllow'
(dateClick)="handleDateClick($event)" [eventSources]="calendarEventSource"
></full-calendar>
NOTICE: Creating a method instead of a property/variable will not work and possibly cause a StackOverflow.
Hope this helps anyone out there with a similar issue!
I have used infragistics igGrid in my application but I am getting javascript error
Object doesn't support property or method "_super"
I know this can be avoided but I want to give it fake implementation (or real answer, may be adding some missing reference) for some reasons. I tried following but not working.
var _super = function(a,s,d,f,g,h) {
}
I have wrote above code before referencing igGrid JS libraries.
In code, _super has variable number of arguments when calling it.
You're probably referencing a version of jQuery UI that still doesn't have _super and _superApply implemented. Try referencing the latest version and the error should go away.
https://bugs.jqueryui.com/ticket/6861
If I understand correctly you are trying to use _super out of scope. You can use _super in the objects scope like this :
(function ($) {
$.ig.RPCDataSource = $.ig.RPCDataSource || $.ig.RESTDataSource.extend({
_processJsonResponse: function (data, context) {
try {
console.log('my special preprocessing');
return this._super(data, context);
} catch (e) {
console.log(e.message);
// my special error handling
}
},
});
}(jQuery));
UPDATE
_super is a method from the jQuery widget factory. iG controls are built upon jQuery Widget. Therefore _super is defined in jQuery widget.
Real quick about jasmine.addMatchers. With the latest Jasmine build from git, it appears as though the format for doing custom matchers is vastly different than code I'm seeing in the 'Jasmine JavaScript Testing' book. In the book it has code such as:
this.actual or maybe even this.isNot
The new format is something like:
compare: function (actual, expected) {
return {
pass: some true or false statement...
}
}
So, in this case, the 'this.actual' is actually the passed in argument 'actual', which is cool. How about accessing the isNot property if we're calling a new matcher such as:
expect(investment).not.toBeAGoodInvestment();
So, inside the body of 'toBeAGoodInvestment', we should be able to access the 'isNot' property. Not sure how to do that with the new format. I figured out how to set the this.message from the old way to the new way as in:
return {
pass: some statement...,
message: 'some message'
}
The message we would want to have show up in the jasmine reporter would be dynamic based on whatever the 'isNot' is set to.
After digging around in the actual Jasmine.js source, I found out where the arguments were getting passed into custom matcher's compare function, and indeed, the 'isNot' was not making it's way in at all. The 'this.isNot' was available in the context of the 'Expectation.prototype.wrapCompare' function within the Jasmine source itself but where it was really needed was the custom matcher I created.
So now in this wrapCompare function, I simply added the args.push statement within the 'if' statement as in:
if (this.isNot) {
//-- Added this line
args.push(this.isNot);
matcherCompare = matcher.negativeCompare || defaultNegativeCompare;
}
Now, calling the matcher, I can do this:
expect(investment).not.toBeAGoodInvestment();
And then the actual matcher it will look something like this:
toBeAGoodInvestment: function () {
return {
compare: function (actual, isNot) {
return {
pass: actual.isGood(),
message: 'Expected investment to be a ' +
((isNot) ? 'bad' : 'good') + ' investment'
}
}
};
}
Nice little research task here to figure out what Jasmine was doing behind the scenes.
Any other way to get the 'isNot' injected into the compare function, let me know.
I recently switched to WebStorm and I'm stuck on an odd problem with javascript prototype modifications. If I define the following:
something.really.neat = function(blah) {
this.dog = "cat"
}
something.really.neat.prototype.getCow = function(blah2) {
this.dog = "cow"
}
Every single call to this.dog in a prototype function results in an "Unresolved variable" error. WebStorm should easily be able to follow the scope from the prototype to the main function but it seems unable to.
The end result of this function is an angular factory:
angular.factory('neat', function() {
return new something.really.neat();
});
5 minutes later I discover its a problem with JSDoc (or at least my syntax). I was using #memberOf on each property and it apparently the syntax I was using for #memberOf was wrong, resulting in WebStorm not being able to locate the scope.
So I'm building a node module for use with node-webkit that creates a new object and exports it. Standard fare. But since Node has no access to the nw-gui module of node-webkit, I'm just passing it in as a parameter to the constructor. Something like this:
function Example(gui) {
this.gui = gui; //Save for later
}
Example.prototype.createExampleMenu = function() {
return new this.gui.Menu();
}
exports.example = Example;
Works great. But I'm trying to modify .prototype methods of node-webkit's inner modules, like Menu and MenuItem. Is the only way to modify those methods (or add new ones) in the constructor itself? If I try to add new prototype methods outside, it (obviously) fails since this.gui hasn't been set. Basically, I'm trying to make it nicer to add new prototype methods to node-webkit modules without doing it in the constructor. Anyone?
I'm in no way an expert but from what I understand of the implementation of node-webkit from reading its source code, I doubt you can modify any of the objects defined in nw.gui.
If you look at the implementation of Node's standard require function in a running node-webkit instance, you'll find:
function (name) {
if (name == 'nw.gui')
return nwDispatcher.requireNwGui();
return global.require(name);
}
which means that requires of nw.gui are very special indeed.
Rather than requiring JavaScript code, this returns an internal binary object that only appears to be a required library.
Looking a little deeper, we find the nwDispatcher.nwGui.Menu is defined as:
function Menu(option) {
if (typeof option != 'object')
option = { type: 'contextmenu' };
if (option.type != 'contextmenu' && option.type != 'menubar')
throw new String('Invalid menu type: ' + option.type);
this.type = option.type;
v8_util.setHiddenValue(this, 'items', []);
nw.allocateObject(this, option);
}
which calls methods of the nw object, which is an object that is not available outside of this function, (i.e. the function acts as a closure over it.)
Further inspection of the various prototype methods of nw.gui.Menu shows that each call refers (internally) to this nw object to handle method dispatch to internally defined functions (written in C++).
So, rather than a group of standard JavaScript prototypical objects, the nw.gui module calls internal binary functions within the node-webkit runtime which are not exposed via its defined API.
UPDATE
From the node-webkit wiki:
Do not change UI types' prototype.