I saw many post like here and here regarding this type error but in my case i
have an object in function like below code and i get this error "Can't execute code from a freed script "
function updateLetterOfClaim(thisletterClaimID) {
var updatedLetter = {};
updatedLetter.new_breaches = top.opener.selected_breach.join(",");//from this line in ie7 i get this error
updatedLetter.new_causation = top.opener.selected_causation.join(",");
updatedLetter.new_chronology = top.opener.chronology_records.join(",");
updatedLetter.new_Injuries = top.opener.damage_records;
}
after see many link and blogs my result come by applying following code
my problem is which i found i apply join() in objects but it apply in array so first i make
my objects in array then apply join ....
function updateLetterOfClaim(thisletterClaimID) {
var updatedLetter = {};
updatedLetter.new_breaches =joinobjects(top.opener.selected_breach);
updatedLetter.new_causation =joinobjects( top.opener.selected_causation);
updatedLetter.new_chronology =joinobjects(top.opener.chronology_records);
updatedLetter.new_Injuries = joinobjects(top.opener.damage_records);
}
function joinobjects(object){
return $.map(object, function(v){
return v;
}).join(', ');
}
Related
I have a canvas pie chart that I'd like to test using protractor.
the html element looks like:
<canvas id ="my_pie" data-values="ctl.gfx.values" data-categories="ctl.gfx.categories"...
In my protractor code I am able to evaluate each attribute data-values and data-categories as follow:
...
var canvas = element(by.css("canvas#my_pie"));
...
canvas.evaluate("ctl.gfx.categories").then(function(c){
console.log(c);
});
canvas.evaluate("ctl.gfx.values").then(function(l){
console.log(v);
});
everything works fine and data is logged out on the console, but if I try to return the arrays themselves, they get returned as empty arrays, I understand this has something to do with promises as that's what the protractor evaluate function stands for but I cannot figure this out because I am totally new to JS, Jasmine and Protractor.
basically the expected logic should be like:
function getMyData(){
var myCategories = [];
var myValues = [];
canvas.evaluate("ctl.gfx.categories").then(function(c){
myCategories = c;
});
canvas.evaluate("ctl.gfx.values").then(function(v){
myValues = v;
});
// do something with both arrays, concat and return a result
//final statement would be a return statement.
}
what I would like to do is return the result of those arrays after some processing but to me it seems like the return statement runs always first, hence the empty result.
You not understand the Async programming/Promise in Protractor, please learn and make you clear the key points this link what to express: http://www.protractortest.org/#/control-flow#promises-and-the-control-flow
Then look into this link I answer other question to explain what happen when run Protracotr script: promise chaining vs promise.all
Then look below, I explained why you always get a empty array in code comment
function getMyData(){
var myCategories = [];
var myValues = [];
canvas.evaluate("ctl.gfx.categories").then(function(c){
myCategories = c;
});
canvas.evaluate("ctl.gfx.values").then(function(v){
myValues = v;
});
// Assume we concat the two array and return the new array as below code shows
var ret = myCategories.concat(myValues);
return ret;
// When JavaScript engine explain and execute below code line:
// var ret = myCategories.concat(myValues);
// the above two canvas.evaluate() have not resoved, because they are
// executed async not sync.
// so the myCategories and myValues have not assigned new value, they are
// still empty array at this time point, so always return empty array
}
To resolve your problem, try below code example:
function getMyData(){
return Promise.all([
canvas.evaluate("ctl.gfx.categories"),
canvas.evaluate("ctl.gfx.values")
]).then(function(data){
let myCategories = data[0];
let myValues = data[1];
return myCategories.concat(myValues);
});
}
getMyData().then(function(myData){
console.log(myData);
// put your code to consume myData at here
})
I have a javascript function like this
function formatInput(input) {
//want to test only this immediate statement
var type = input.ipType.toString().toLowerCase().trim();
var afterVormat = someFunction(type);
return afterFormat;
}
I am able to test this function(value of afterFormat) correctly , but is it possible/how to test a specific line in function since I am not returning type.
For example I want to test if var type is as it is expected
Is it possible/how to test a specific line in function?
The immediate answer: no.
The solution
One of the outcomes of adhering to TDD is that it forces you to build code in isolated, testable blocks. This is a direct consequence of the fact that you cannot perform test(s) of the individual lines of a function. In your case the solution is to restructure your code to:
var type = function(){
return input.ipType.toString().toLowercase().trim();
};
function formatInput(input) {
var type2 = type();
var afterVormat = someFunction(type);
return afterFormat;
}
Now you have made type an isolated block that you can test.
If you combine this with use of Sinon.JS you can use a spy to test that an invocation of function formatInput() will also result in the invocation of type() and thereby you know for sure that var type2 has been assigned the intended value.
I’m not aware of any specific and more advanced unit testing method/system for javascript, but you can have a simple assertion function to test individual lines of code for debugging purpose like this:
function assert(condition, message) {
if (!condition) {
message = message || "Assertion failed";
if (typeof Error !== "undefined") {
throw new Error(message);
}
throw message; // Fallback
}
}
(Code taken from TJ Crowder's answer to another question.)
Then you can just use it to check for instance the var type like this:
assert(type == "something expected here and shall throw an error otherwise");
You can use console.log() function for that. As below.
function formatInput(input) {
var type = input.ipType.toString().toLowerCase().trim();
console.log(type);
var afterVormat = someFunction(type);
return afterFormat;
}
Also you can use debugger; also, to debug the code line by line.
function formatInput(input) {
var type = input.ipType.toString().toLowerCase().trim();
debugger;
var afterVormat = someFunction(type);
return afterFormat;
}
and just press F10 key to debug the code and you can check the values in console.
I found this example from Ryan Niemeyer and started to manipulate it into the way I write my own code, but then it stopped working. Can anybody tell me why?
Alternative 1 is my variant
Alternative 2 is based upon Ryans solution and does work (just comment/uncomment the Applybindings).
Why doesn´t Alternative 1 work?
My issue is with the filteredRows:
self.filteredRows = ko.dependentObservable(function() {
//build a quick index from the flags array to avoid looping for each item
var statusIndex = {};
ko.utils.arrayForEach(this.flags(), function(flag) {
statusIndex[flag] = true;
});
//return a filtered list
var result = ko.utils.arrayFilter(this.Textbatches(), function(text) {
//check for a matching genré
return ko.utils.arrayFirst(text.genre(), function(genre) {
return statusIndex[genre];
});
return false;
});
console.log("result", result);
return result;
});
I want to filter my Textbatches on the genre-attribute (string in db and the data collected from the db is a string and not an array/object)
Fiddle here: http://jsfiddle.net/gsey786h/6/
You have various problems, most of them can be simply fixed with checking your browser's JavaScript console and reading the exceptions...
So here is the list what you need to fix:
You have miss-typed Textbatches in the declaration so the correct is self.Textbatches = ko.observableArray();
You have scoping problem in filteredRows with the this. So if you are using self you should stick to it and use that:
this.flags() should be self.flags()
this.Textbatches() should be self.Textbatches()
Your genre property has to be an array if you want to use it in ko.utils.arrayFirst
Finally your Textbatch takes individual parameters but you are calling it with an object, so you need to change it to look like:
Textbatch = function(data) {
var self = this;
self.id = ko.observable(data.id);
self.name = ko.observable(data.name);
self.statuses = ko.observableArray(data.status);
self.genre = ko.observableArray(data.genre);
self.createdBy = ko.observable(data.createdBy);
};
or you can of course change the calling places to use individual arguments instead of an object.
Here is a working JSFiddle containing all the above mentioned fixes.
i have a problem using a class methods, after it was inserted into array. when i pull it back i can no longer use it methods.
and i know javascript does not have class, when i say class i mean object -or js equal.
suppose i have the following:
// a simple atomic class
function raw_msg(msg) {
this.msg = msg;
this.print = function () {
console.log(this.msg);
}
}
// and then i have this container for this "atomic" class
// which accept array of unknown object (known to me though..) = in_buffer
// i.e in_buffer is just an array of objects (one type of object)
function buffer(in_buffer) {
this.trans_buffer = null;
if (in_buffer!=null)
this.set_buffer (in_buffer);
this.set_buffer = function (buffer) {
this.trans_buffer = [];
var length = buffer.length,
row, new_raw_msg;
for(var x = 0; x < length; x++) {
row = buffer[x];
this.trans_buffer.push(new raw_msg(row));
}
console.log(this.trans_buffer);
}
this.use_some_raw_msg_method = function () {
var firstrow = this.trans_buffer[0];
firstrow.print(); // here is the problem!!!
//this here where i need help as it yield the error:
//Uncaught TypeError: Object #<Object> has no method 'print'
}
}
// this is how i use it, this code sits in a diffrent yet another class...
// this here im just building fake array
var buffer_in = [];
for (var x=0;x<10;x++)
buffer_in.push ("whatever" + x);
this.trans_buffer = new trans_helper(buffer_in);
this.trans_buffer.use_some_raw_msg_method (); // will yield the error as described
i hope this here, is clear, ask away if you need clarifications.
thanks for your help!
note to future readers - there is no problem in retrieving an object and using its methods.
You had several problems with your code.
Associative array does not have .push() method so the following line failed:
buffer_in.push ("whatever" + x);
To fix this just declare plain array:
var buffer_in = [];
You tried to create instance of function called trans_helper which does not exist. The name is buffer instead, so fix would be:
var trans_buffer = new buffer(buffer_in);
Last but not least, you tried to call function in the "class" when it still did not exist yet. JavaScript does not "compile" functions in advance, when inside function it will go line by line. So in this line in your code:
this.set_buffer (in_buffer);
There was still no function called "set_buffer" in your class. To fix this, place the function declaration above, on top.
Live test case.
I have something like this:
var test = {};
function blah() {
test[2] = 'filled';
}
blah(); // ! Hopefully confusion is now averted..
console.log(test);
//result test -> 2:"filled"
console.log(test[2]);
//result undefined
I don't understand why I'm getting 'undefined' in the second instance when according to the first instance, the property of that object clearly exists!
Does anyone have any ideas?
Thanks
OK, it seems that folk are getting confused as to what context the code exists in, for clarity sake I have now added the call to the blah(). but please refer to the comment under Jeff B's response!
Here is an example of relevant code so to say:
mydb = ..... //gets created here with relevant credentials
var test = {};
mydb.transaction(
function(transaction) {
transaction.executeSql("select * from mytable;", [], function(transaction,result) {
var r = result.rows.item(0);
test[2] = r.title;
}, errorHandler);
});
console.log(test);
//result test -> 2:"the title"
console.log(test[2]);
//result undefined
#Dancrumb
Your mention of the single-threadedness of Javascript gave me an idea, and I tried this:
window.setTimeout(function(){ alert(test[2]); },2000);
and it worked! I got the expected value to alert. Can you suggest how I can get around this without using a 'hack' like that above?
Because you aren't calling blah()?
Also, you want:
var test = [];
or:
var test = new Array();
EDIT
I ran the following code:
mydb = openDatabase('note','','Example',1024);
var test = {};
mydb.transaction(
function(transaction) {
transaction.executeSql("select * from mytable;", [], function(transaction,result) {
var r = result.rows.item(0);
test[2] = r.title;
}, errorHandler);
});
console.log(test);
console.log(test[2]);
in Safari 4.0.5
I got the following:
Object
No Properties
undefined
This is what I would expect to see. The object test does not have any properties assigned to it until the callback from mydb.transaction occurs and, since Javascript is single threaded, this cannot happen before the calls to console.log.
Since you're getting a different outcome, can you outline what browser and what version you are using?
This is pretty clearly an asynchronous issue. The simplest way of getting code to run after you set test[2], is to either put the code right there, or use another callback, and call it after you set test[2].