I'm struggling trying to understand why this script works perfectly in the browser but not in Node.js in the server.
data = [{"stars": 3}, {"stars": 2}]
var ParseParameter = function(){
this.parser = "";
}
ParseParameter.prototype = {
setStrategy: function(parser) {
this.parser = parser;
},
parse: function(parameter) {
return this.parser.parse(parameter);
}
};
var IntegerParser = function(filter){
this.parameter = '';
this.filter = filter;
this.parse = function(parameter){
this.parameter = parseInt(parameter);
}
this.filterBy = function(item){
return item[this.filter] == this.parameter;
}
}
var filter = 'stars',
parameter = '2',
parseParameter = new ParseParameter();
var integerParser = new IntegerParser(filter);
parseParameter.setStrategy(integerParser);
parseParameter.parse(parameter);
var dataFiltered = data.filter(parseParameter.parser.filterBy);
console.log(dataFiltered);
At the server, I print in console the values of this.parameter and this.filter at the function filterBy and these are undefined
I'm running on Node.js version 8.11.2
Any advice will be appreciated.
The is may be due to problem of this keyword in your script. Inside an inner function this refers to window or global object. For example,
Inside the following code, this.filter of this.filterBy is not referring to the filter property that exists inside the scope of IntegerParser function instead it is referring the variable being defined as var filter = 'stars'. Change this name to something else and you'll see undefined and it won't work on browser as well. That's what could be your issue.
var IntegerParser = function(filter){
this.parameter = '';
this.filter = filter;
this.parse = function(parameter){
this.parameter = parseInt(parameter);
}
this.filterBy = function(item){
return item[this.filter] == this.parameter;
}
}
Instead of using this you could use a known solution for this problem by storing this to a variable for later usage. like in following example:
var IntegerParser = function(filter){
this.parameter = '';
this.filter = filter;
var self = this; // store this to self and use self in inner functions
this.parse = function(parameter){
self.parameter = parseInt(parameter);
}
this.filterBy = function(item){
return item[self.filter] == self.parameter;
}
}
Your entire code including my solution is as follow:
data = [{"stars": 3}, {"stars": 2}]
var ParseParameter = function(){
this.parser = "";
}
ParseParameter.prototype = {
setStrategy: function(parser) {
this.parser = parser;
},
parse: function(parameter) {
return this.parser.parse(parameter);
}
};
var IntegerParser = function(filter){
this.parameter = '';
this.filter = filter;
var self = this;
this.parse = function(parameter){
self.parameter = parseInt(parameter);
}
this.filterBy = function(item){
return item[self.filter] == self.parameter;
}
}
var filter = 'stars',
parameter = '2',
parseParameter = new ParseParameter();
var integerParser = new IntegerParser(filter);
parseParameter.setStrategy(integerParser);
parseParameter.parse(parameter);
var dataFiltered = data.filter(parseParameter.parser.filterBy);
console.log(dataFiltered);
It should work without any problem. Please try and see if it works for you.
Related
I want to restrict the user from adding more product to sell if the order is tag as booked order
I want to show popup error message when it is booked order and the user still click the product
here is my code
odoo.define('tw_pos_inherit_model.attemptInherit', function (require) {
"use strict";
var POSInheritmodel = require('point_of_sale.models');
var ajax = require('web.ajax');
var BarcodeParser = require('barcodes.BarcodeParser');
var PosDB = require('point_of_sale.DB');
var devices = require('point_of_sale.devices');
var concurrency = require('web.concurrency');
var config = require('web.config');
var core = require('web.core');
var field_utils = require('web.field_utils');
var rpc = require('web.rpc');
var session = require('web.session');
var time = require('web.time');
var utils = require('web.utils');
var gui = require('point_of_sale.gui');
var orderline_id = 1;
var QWeb = core.qweb;
var _t = core._t;
var Mutex = concurrency.Mutex;
var round_di = utils.round_decimals;
var round_pr = utils.round_precision;
var _super_order = POSInheritmodel.Order.prototype;
POSInheritmodel.Order = POSInheritmodel.Order.extend({
add_product: function(product, options){
var can_add = true;
var changes = this.pos.get_order();
var self = this;
try{
if(changes.selected_orderline.order.quotation_ref.book_order){
can_add= false;
}
}catch(err){}
if (can_add){
if(this._printed){
this.destroy();
return this.pos.get_order().add_product(product, options);
}
this.assert_editable();
options = options || {};
var attr = JSON.parse(JSON.stringify(product));
attr.pos = this.pos;
attr.order = this;
var line = new POSInheritmodel.Orderline({}, {pos: this.pos, order: this, product: product});
if(options.quantity !== undefined){
line.set_quantity(options.quantity);
}
if(options.price !== undefined){
line.set_unit_price(options.price);
}
//To substract from the unit price the included taxes mapped by the fiscal position
this.fix_tax_included_price(line);
if(options.discount !== undefined){
line.set_discount(options.discount);
}
if(options.discount_percentage !== undefined){
line.set_if_discount_percentage(options.discount_percentage);
}
if(options.discount_amount !== undefined){
line.set_if_discount_amount(options.discount_amount);
}
if(options.extras !== undefined){
for (var prop in options.extras) {
line[prop] = options.extras[prop];
}
}
var to_merge_orderline;
for (var i = 0; i < this.orderlines.length; i++) {
if(this.orderlines.at(i).can_be_merged_with(line) && options.merge !== false){
to_merge_orderline = this.orderlines.at(i);
}
}
if (to_merge_orderline){
to_merge_orderline.merge(line);
} else {
this.orderlines.add(line);
}
this.select_orderline(this.get_last_orderline());
if(line.has_product_lot){
this.display_lot_popup();
}
}else{
self.gui.show_popup('error',{
title :_t('Modification Resctricted'),
body :_t('Booked Order cannot be modified'),
});
}
},
});
});
but im getting an error
Uncaught TypeError: Cannot read property 'show_popup' of undefined
http://localhost:8071/web/content/554-cbfea6c/point_of_sale.assets.js:475
Traceback:
TypeError: Cannot read property 'show_popup' of undefined
at child.add_product (http://localhost:8071/web/content/554-cbfea6c/point_of_sale.assets.js:475:116)
at Class.click_product (http://localhost:8071/web/content/554-cbfea6c/point_of_sale.assets.js:326:257)
at Object.click_product_action (http://localhost:8071/web/content/554-cbfea6c/point_of_sale.assets.js:325:951)
at HTMLElement.click_product_handler (http://localhost:8071/web/content/554-cbfea6c/point_of_sale.assets.js:320:1738)
im sorry im really confuse do i still need to initialized the this.gui first?
even though i have var gui = require('point_of_sale.gui'); initialized already
when i log the this.gui to my console the output is undefined
You can access gui via posModel.
self.pos.gui.show_popup('error',{
title :_t('Modification Resctricted'),
body :_t('Booked Order cannot be modified'),
});
You can check an example at connect_to_proxy
I am using ngStorage to store data. I made a custom objects called game and stored it. Its stored as a game but when i refresh the browser it comes back as an Object.
var games= $localStorage.games || {};
this.addGame = function(){
var newGame = new game("Game "+games.length);
$localStorage.games = newGame;
}
var game = function(title){
var title=title;
var player1;
var player2;
this.getTitle = function(){
return title;
}
this.setTitle = function(title){
this.title = title;
}
this.getPlayer1 = function(){
return player1;
}
this.setPlayer1 = function(player1){
this.player1 = player1;
}
this.getPlayer2 = function(){
return player2;
}
this.setPlayer1 = function(player1){
this.player2 = player2;
}
}
When a new game is added it's stored as a game in LocalStorage but when I refresh the bowser and tried to fetch games. It returns as an array of Objects not games.
You cannot store objects in localStorage. The hack is that you can store string and parse/unparse them like this.
var game = {
name: 'Super Metroid',
text: 'This is an awesome game!!!'
};
window.localStorage['game'] = JSON.stringify(game);
var superMetroid = JSON.parse(window.localStorage['game'] || '{}');
I am building a Windows 8 Store app with HTML/CSS/JavaScript. I am reading in data from a text file through a function, and then putting that data into an array. I am trying to return the array through the function, but it is not working. Any help would be greatly appreciated. I've attached my code snippet.
// Load user data
var DefineUserData = function LoadUserData() {
return Windows.Storage.ApplicationData.current.localFolder.getFileAsync(loadfile).done(function (UserFile) {
return Windows.Storage.FileIO.readTextAsync(UserFile).done(function (fileResult) {
var userdata = new Object();
var dataobject = {};
var innercount;
var outercount;
var fileResultByLines = fileResult.split("\n");
for (outercount = 0; outercount <= (fileResultByLines.length - 2) ; outercount++) {
var tempArray = fileResultByLines[outercount].split(",");
dataobject.metrictitle = tempArray[0];
dataobject.numinputs = tempArray[1];
dataobject.inputs = new Array();
for (innercount = 0; innercount <= parseInt(dataobject.numinputs) ; innercount++) {
dataobject.inputs[innercount] = tempArray[innercount + 2];
}
userdata[outercount] = dataobject;
}
return userdata;
});
},
function (errorResult) {
document.getElementById("resbutton1").innerText = errorResult;
})
}
Your DefineUserData function is returning a Promise, not a value. Additionally done functions don't return anything. Instead you'll need to use then functions instead of done functions in DefineUserData and then handle add a done function (or then) to the code that calls this function.
Also, You can make your promises easier to read, and easier to work with by chaining then functions instead of nesting them.
Currently on Win7 at the office so I can't test this, but try something similar to this pseudo-code. Note then functions instead of done. The last then returns your data. Sample snippet afterwards to illustrate calling this and handling the result.
// modified version of yours
var DefineUserData = function LoadUserData() {
return Windows.Storage.ApplicationData.current.localFolder
.getFileAsync(loadfile)
.then(function (UserFile) {
return Windows.Storage.FileIO.readTextAsync(UserFile);
}).then(function (fileResult) {
var userdata = new Object();
var dataobject = {};
var innercount;
var outercount;
var fileResultByLines = fileResult.split("\n");
for (outercount = 0; outercount <= (fileResultByLines.length - 2) ; outercount++) {
var tempArray = fileResultByLines[outercount].split(",");
dataobject.metrictitle = tempArray[0];
dataobject.numinputs = tempArray[1];
dataobject.inputs = new Array();
for (innercount = 0; innercount <= parseInt(dataobject.numinputs) ; innercount++) {
dataobject.inputs[innercount] = tempArray[innercount + 2];
}
userdata[outercount] = dataobject;
}
return userdata;
},
function (errorResult) {
document.getElementById("resbutton1").innerText = errorResult;
});
}
// some other code...
DefineUserData.done(function (userdata) {
// do something
});
I tried to use following code to test the performance of IndexedDB.
The code is modified from http://www.html5rocks.com/en/tutorials/indexeddb/todo/ ,
It works well in chrome, but fails in Firefox 10, saying "db.setVersion is not a function".
I want to know how can I modify the code to make it work in firefox?
var count=0;
var MAX=10;
var times=3;
var allTime;
var stime;
var etime;
var html5rocks = {};
var indexedDB = window.indexedDB || window.webkitIndexedDB ||
window.mozIndexedDB;
if ('webkitIndexedDB' in window) {
window.IDBTransaction = window.webkitIDBTransaction;
window.IDBKeyRange = window.webkitIDBKeyRange;
}
html5rocks.indexedDB = {};
html5rocks.indexedDB.db = null;
html5rocks.indexedDB.onerror = function(e) {
//console.log(e);
alert("Why didn't you allow my web app to use IndexedDB?!");
};
html5rocks.indexedDB.open = function(type) {
var request = indexedDB.open("todos");
request.onsuccess = function(e) {
var v = "1.20";
html5rocks.indexedDB.db = e.target.result;
var db = html5rocks.indexedDB.db;
// We can only create Object stores in a setVersion transaction;
if (v!= db.version) {
var setVrequest = db.setVersion(v);
// onsuccess is the only place we can create Object Stores
setVrequest.onerror = html5rocks.indexedDB.onerror;
setVrequest.onsuccess = function(e) {
if(db.objectStoreNames.contains("todo")) {
db.deleteObjectStore("todo");
}
var store = db.createObjectStore("todo",
{keyPath: "number"});
addTest();
};
}
else addTest();
};
request.onerror = html5rocks.indexedDB.onerror;
}
html5rocks.indexedDB.addTodo = function(todoText,num) {
var db = html5rocks.indexedDB.db;
var trans = db.transaction(["todo"], IDBTransaction.READ_WRITE);
var store = trans.objectStore("todo");
var data = {
"text": todoText,
"number": num
};
var request = store.put(data);
request.onsuccess = function(e) {
count++;
if(count>=times*MAX)
{
etime=new Date;
var t=document.getElementById('result').innerHTML;
document.getElementById('result').innerHTML=t+((etime.valueOf()-stime.valueOf())/times)+"<br/>";
allTime=0;stime=new Date;count=0;
getTest();
}
};
request.onerror = function(e) {
console.log("Error Adding: ", e);
};
};
html5rocks.indexedDB.getTodo = function(id) {
var db = html5rocks.indexedDB.db;
var trans = db.transaction(["todo"], IDBTransaction.READ_WRITE);
var store = trans.objectStore("todo");
var request = store.get(id);
request.onsuccess = function(e) {
count++;
if(count>=times*MAX)
{
etime=new Date;
var t=document.getElementById('result').innerHTML;
document.getElementById('result').innerHTML=t+((etime.valueOf()-stime.valueOf())/times)+"<br/>";
allTime=0;stime=new Date;count=0;
delTest();
}
};
request.onerror = function(e) {
console.log("Error getting: ", e);
};
};
html5rocks.indexedDB.deleteTodo = function(id) {
var db = html5rocks.indexedDB.db;
var trans = db.transaction(["todo"], IDBTransaction.READ_WRITE);
var store = trans.objectStore("todo");
var request = store.delete(id);
request.onsuccess = function(e) {
count++;
if(count>=times*MAX)
{
etime=new Date;
var t=document.getElementById('result').innerHTML;
document.getElementById('result').innerHTML=t+((etime.valueOf()-stime.valueOf())/times)+"<br/>";
allTime=0;stime=new Date;count=0;
dataTest();
}
};
request.onerror = function(e) {
console.log("Error Adding: ", e);
};
};
html5rocks.indexedDB.addData = function(d) {
var db = html5rocks.indexedDB.db;
var trans = db.transaction(["todo"], IDBTransaction.READ_WRITE);
var store = trans.objectStore("todo");
var data={
"text":d,
"number":1
};
var request = store.put(data);
request.onsuccess = function(e) {
etime=new Date;
var t=document.getElementById('result').innerHTML;
document.getElementById('result').innerHTML=t+((etime.valueOf()-stime.valueOf()))+"<br/>";
};
request.onerror = function(e) {
console.log("Error Adding: ", e);
};
};
function addTest() {
for(i=1;i<=times*MAX;i++)
html5rocks.indexedDB.addTodo(' ',i);
}
function getTest() {
for(i=1;i<=times*MAX;i++)
html5rocks.indexedDB.getTodo(Math.round(Math.random()*(MAX*times-1)+1));
}
function delTest() {
for(i=1;i<=times*MAX;i++)
html5rocks.indexedDB.deleteTodo(i);
}
function dataTest() {
data=' ';
for(i=1;i<=21;i++)
data=data+data;
stime=new Date
html5rocks.indexedDB.addData(data);
}
function init() {
stime=new Date;
allTime=0;
html5rocks.indexedDB.open();
}
The spec is not finalized. This is currently shipped as the property mozIndexedDB in Gecko and webkitIndexedDB in Chrome until the standard is finalized. So you have to write for moz also. Now this code is only for webkit.
https://developer.mozilla.org/en/IndexedDB
setVersion() is Deprecated
The new way is to define the version in the IDBDatabase.open() method
firefox from version 10.0 implements open() with the new specification in which an indexeddb database IDBDatabase version is set as the second parameter of the open() method
example
var v = "1.20";
var request = indexedDB.open("todos", v);
html5 indexeddb javascript
The problem here is not the one chosen as the correct answer.
The problem is that the IndexedDB examples on HTML5Rocks were written to the pre-January IndexeDB spec. The working group has since published a breaking change going from the setVersion API to the new onupgradedneeded style.
Here, Firefox is technically correct to fail. Star this issue if you want to see Chrome do the same.
I have this :
var MyObject = function(){
this.url = "monurl";
this.mavar = "";
this.Load = function(){
var callback = {
success: function(o){
mavar = o.responseXML.getElementsByTagName("montag")[0].firstChild.nodeValue;
}
}
YAHOO.util.Connect.asyncRequest('GET',url,callback);
} }
the mavar variable is not accessible. How can I do this ?
I believe you can set a scope param to the callback. So you should be able to do something like the following.
var MyObject = function(){
this.url = "monurl";
this.mavar = "";
this.Load = function(){
var callback = {
success: function(o){
this.mavar = o.responseXML.getElementsByTagName("montag")[0].firstChild.nodeValue;
},
scope: this
}
YAHOO.util.Connect.asyncRequest('GET', this.url, callback);
} }
You could also do it like this:
var MyObject = new function(){
this.url = "monurl";
this.mavar = "";
this.Load =
(function(that){
return function(){
var callback = {
success: function(o){
that.mavar = o.responseXML.getElementsByTagName("montag")[0].firstChild.nodeValue;
}
}
YAHOO.util.Connect.asyncRequest('GET',url,callback);
}
})(this);
};
In my object, I add a variable that's reference the this :
var selfMyObject = this;
and I replace the this.mavar to selfMyObject.mavar in success callback and it's work fine.
Save the this variable:
var MyObject = function() {
this.url = "monurl";
this.mavar = "";
this.Load = function() {
var me = this;
var callback = {
success: function(o) {
me.mavar = o.responseXML.getElementsByTagName("montag")[0].firstChild.nodeValue;
}
}
YAHOO.util.Connect.asyncRequest('GET',url,callback);
}
}
The best way to handle this is to let YUI do your scope correction, since support is built in. Here's the docs page telling you how to to do it. http://developer.yahoo.com/yui/connection/#scope
var MyObject = function() {
this.url = "monurl";
this.mavar = "";
this.Load = function() {
var callback = {
success: function(o){
this.mavar = o.responseXML.getElementsByTagName("montag")[0].firstChild.nodeValue;
},
scope: this
}
YAHOO.util.Connect.asyncRequest('GET', url, callback);
}
}