I am trying to send collection of JavaScript objects to my API service, But server receive empty object list!
<script>
//Collection
var Collection = function () {
this.count = 0;
this.collection = {};
this.add = function (key, item) {
if (this.collection[key] != undefined)
return undefined;
this.collection[key] = item;
return ++this.count
}
this.remove = function (key) {
if (this.collection[key] == undefined)
return undefined;
delete this.collection[key]
return --this.count
}
this.item = function (key) {
return this.collection[key];
}
this.forEach = function (block) {
for (key in this.collection) {
if (this.collection.hasOwnProperty(key)) {
block(this.collection[key]);
}
}
}
}
// the JavaScript class for food
function foodcls(no,qunt,name, cals, carb, fat, prt,unt) {
this.no = no;
this.qunt = qunt;
this.name = name;
this.cals = cals;
this.carb = carb;
this.fat = fat;
this.prt = prt;
this.unt = unt;
}
// instantiate new obj
var fod = new foodcls(3, 5, 'SomeName', 300, 180, 100, 20, 'Gram');
var fno =333;
var timCol = new Collection();
timCol.add(fno, fod);
var urlpaths = '/api/FoodServ';
$.ajax({
url: urlpaths,
method: "POST",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(timCol),
success: function (data) {
// any thing
}
});
</script>
Code in ASP.NET API :
[HttpPost]
public HttpResponseMessage Post(List<foodcls> fods) // Here fods is empty
{
int rslt=0;
string UserId = "sam#am.com";//User.Identity.Name;
List<Foods_Meal_TBL> fooditems = new List<Foods_Meal_TBL>();
if (fods.Count()>0)
{
foreach (foodcls item in fods)
{
Foods_Meal_TBL fooditem = new Foods_Meal_TBL();
fooditem.FoodNo = item.no;
fooditem.Quantity = item.qunt;
fooditem.PersonID = UserId;
fooditems.Add(fooditem);
}
}
rslt = SaveAllItems(fooditems); // rslt Meal No
return Request.CreateResponse(HttpStatusCode.OK, rslt);
}
Any help please ?
I found away to solve the issue by convert the collection to array, I know it is not the best solution, And I hope someone could find better solution that avoid use array, but until someone give a better answer, I put my way to fix that as below:
I have added the function toArr // means covert collection to array as below:
//Collection
var Collection = function () {
this.count = 0;
this.collection = {};
this.add = function (key, item) {
if (this.collection[key] != undefined)
return undefined;
this.collection[key] = item;
return ++this.count
}
this.remove = function (key) {
if (this.collection[key] == undefined)
return undefined;
delete this.collection[key]
return --this.count
}
this.item = function (key) {
return this.collection[key];
}
this.forEach = function (block) {
for (key in this.collection) {
if (this.collection.hasOwnProperty(key)) {
block(this.collection[key]);
}
}
}
this.toArr = function (block) { //ToArray
var fodarr = [];
for (key in this.collection) {
if (this.collection.hasOwnProperty(key)) {
fodarr.push(this.collection[key]);// block(this.collection[key]);
}
}
return fodarr;
}
}
ASP.NET API function :
[HttpPost]
public HttpResponseMessage Post(foodcls[] fods)
Hope that help someone in future...
You can add method inside your Collection for converting you local collection to JSON object.
var Collection = function () {
this.count = 0;
this.collection = {};
this.add = function (key, item) {
if (this.collection[key] != undefined)
return undefined;
this.collection[key] = item;
return ++this.count
}
this.remove = function (key) {
if (this.collection[key] == undefined)
return undefined;
delete this.collection[key]
return --this.count
}
this.item = function (key) {
return this.collection[key];
}
this.toJSON = function(){
return JSON.stringify(this.collection);
}
this.forEach = function (block) {
for (key in this.collection) {
if (this.collection.hasOwnProperty(key)) {
block(this.collection[key]);
}
}
}
}
Hope, it will help. Also suggestion: do not use objects for storing values, because they are slower then arrays.
Related
My Bookmark Service which stores a result item with JSON structure doesn't work well.
Probably the issue comes from the array that doesn't work with the local storage function.
I've tried to JSON.stringify my items.
var key = 'fud_bookmarks';
var bookmarks = [];
this.addBookmark = function(resultItem) {
var bookmarks = this.getBookmarks();
bookmarks.push(resultItem);
return setBookmarks(bookmarks);
};
this.deleteBookmark = function(resultItem) {
var bookmarks = this.getBookmarks();
var i = bookmarks.indexOf(resultItem);
if (i >= 0) {
bookmarks.splice(i, 1);
console.log(bookmarks)
return setBookmarks(bookmarks);
}
return false;
};
this.getBookmarkCount = function() {
return getBookmarks().length;
};
this.getBookmarks = function() {
var bookmarks = localStorage.getItem(key);
if (!bookmarks) {
bookmarks = [];
}
return bookmarks;
}
function setBookmarks(bookmarks) {
return localStorage.setItem(key, bookmarks);
}
The resulted items look like this.
{
id: "112",
docType: "doctyp117",
title: "Abschließender Bericht über die Arbeit des Kunsts…- September 1944, Exemplar für Tieschowitz, o.D.",
type: "Archivbestand",
description: null,
…
}
$$hashKey: "object:455"
archive: {
id: "24",
title: "Familienarchiv der Grafen Wolff Metternich zur Gracht"
}
right now I get this error in the console =>
bookmarks.push is not a function
at Object.addBookmark (bookmark.js:12)
localStorage store a string values, not an objects.
If you want to store an Array should stringify it.
function setBookmarks(bookmarks) {
return localStorage.setItem(key, JSON.stringify(bookmarks));
}
this.getBookmarks = function () {
var bookmarks = JSON.parse(localStorage.getItem(key));
...
https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
If value in starage will be not a valid JSON JSON.parse method throw an error, so you can use a try catch to avoid errors:
this.getBookmarks = function () {
var bookmarks;
try {
bookmarks = JSON.parse(localStorage.getItem(key));
} catch (e) {
bookmarks = [];
}
...
deleteBookmark should looks like:
this.deleteBookmark = function (resultItem) {
var i = 0;
let bookmarks = this.getBookmarks();
for (;i < bookmarks.length - 1;i++) {
if (resultItem.id === bookmarks[i].id) {
break;
}
}
if (i >= 0) {
bookmarks.splice(i, 1);
console.log(bookmarks)
return setBookmarks(bookmarks);
}
return false;
}
Try this: Check if typeof bookmarks is not object then return empty array. As Array is also a special type of object in javascript.
this.getBookmarks = function() {
var bookmarks = localStorage.getItem(key);
if (typeof bookmarks !== "object") {
bookmarks = [];
};
return bookmarks;
};
I'm working through Cracking the Coding Interview and I thought I'd implement all the data structures in JS 5. Can anyone explain to me why my toString method isn't working?
Thanks!
function Node(data) {
this.next = null;
this.data = data;
}
Node.prototype.appendToTail = function(data) {
var end = new Node(data);
var n = this;
while (n.next != null) {
n = n.next;
}
n.next = end;
}
Node.prototype.toString = function(head) {
console.log(head)
if (head == null) {
return ""
} else {
return head.data.toString() + "-> " + head.next.toString();
}
}
var ll = new Node(1);
ll.appendToTail(3);
ll.appendToTail(4);
console.log(ll.toString())
function Node(data) {
this.next = null;
this.data = data;
}
Node.prototype.appendToTail = function(data) {
var end = new Node(data);
var n = this;
while (n.next != null) {
n = n.next;
}
n.next = end;
};
Node.prototype.toString = function() {
var returnValue = String(this.data);
if (this.next) {
returnValue = returnValue + "-> " + String(this.next);
}
return returnValue;
};
var ll = new Node(1);
ll.appendToTail(3);
ll.appendToTail(4);
console.log(String(ll))
or avoid this kind of problems completly and do not use prototype, class, this, call, etc
Your toString function takes an argument, but you're not passing it when you call toString.
If you want to access the node, you should use this, instead of passing in a value
Node.prototype.toString = function() {
var result = this.data.toString();
if (this.next) {
result += "-> " + this.next.toString();
}
return result;
}
I am trying to create tree like component,
for the first level data is coming from the server ,
if the user clicks the node i need to populate the child nodes with the data from service call.
what is the best way to save the data for this tree component ?
because user will do some operations on the tree component like remove, add & move. Finally i need to send the updated data to the server .
This is the hashmap functionality I use in javascript.
I based it off the docs of java 7 hashmap.
http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
I added the load and save variables to allow JSON storage. be careful though. if you stored any complex objects(like a hashmap in a hashmap) you will lose that.
You'd have to implement your own object instantiatiors in the load and save function.
A JSfiddle to play with if you like:
http://jsfiddle.net/mdibbets/s51tubm4/
function HashMap() {
this.map = {};
this.listsize = 0;
}
HashMap.prototype._string = function(key) {
if(typeof key.toString !== 'undefined') {
return key.toString();
}
else {
throw new Error('No valid key supplied. Only supply Objects witha toString() method as keys');
}
}
HashMap.prototype.put = function(key,value) {
key = this._string(key);
if(typeof this.map[key] === 'undefined') {
this.listsize++;
}
this.map[key] = value;
}
HashMap.prototype.get = function(key) {
key = this._string(key);
return this.map[key];
}
HashMap.prototype.containsKey = function(key) {
key = this._string(key);
return !(this.map[key] === 'undefined');
}
HashMap.prototype.putAll = function(hashmap) {
if(hashmap instanceof HashMap) {
var othermap = hashmap.map;
for(var key in othermap) {
if(othermap.hasOwnProperty(key)) {
if(typeof this.map[key] === 'undefined') {
this.listsize++;
}
this.map[key] = othermap[key];
}
}
}
else {
throw new Error('No HashMap instance supplied');
}
}
HashMap.prototype.remove = function(key) {
key = this._string(key);
var ret = null;
if(typeof this.map[key] !== 'undefined') {
ret = this.map[key];
delete this.map[key];
this.listsize--;
}
return ret;
}
HashMap.prototype.clear = function() {
this.map = {};
this.listsize = 0;
}
HashMap.prototype.containsValue = function(value) {
for(var key in this.map) {
if(this.map.hasOwnProperty(key)) {
if(this.map[key] === value) {
return true;
}
}
}
return false;
}
HashMap.prototype.clone = function() {
var ret = new HashMap();
ret.map = this.map;
ret.listsize = this.listsize;
return ret;
}
HashMap.prototype.entrySet = function() {
return this.map;
}
HashMap.prototype.keySet = function() {
var ret = [];
for(var key in this.map) {
if(this.map.hasOwnProperty(key)) {
ret.push(key);
}
}
return ret;
}
HashMap.prototype.values = function() {
var ret = [];
for(var key in this.map) {
if(this.map.hasOwnProperty(key)) {
ret.push(this.map[key]);
}
}
return ret;
}
HashMap.prototype.size = function(activeCheck) {
//Active check is expensive.
if(typeof activeCheck !== 'undefined' && activeCheck) {
var count = 0;
for(var key in this.map) {
if(this.map.hasOwnProperty(key)) {
count++;
}
}
return count;
}
return this.listsize;
}
HashMap.prototype.save = function(){
return JSON.stringify(this.map);
}
HashMap.prototype.load = function(json) {
if(typeof json !== 'string') {
throw new Error("No valid input supplied. Only supply JSON Strings");
}
this.map = JSON.parse(json);
this.listsize = this.size(true);
}
var map = new HashMap();
console.log(
map.put('hello', true),
map.get('hello'),
map.put('hello',10),
map.put('world',20),
map.values(),
map.keySet(),
map.entrySet(),
map.containsValue('twoshoes'),
map.size()
);
var map2 = new HashMap();
map2.put('goody','twoshoes');
map2.putAll(map);
console.log(
map2.get('hello'),
map2.values(),
map2.keySet(),
map2.entrySet(),
map2.containsValue('twoshoes'),
map2.size()
);
var map3 = new HashMap();
map3.load(map2.save());
console.log(
map3.get('hello'),
map3.values(),
map3.keySet(),
map3.entrySet(),
map3.containsValue('twoshoes'),
map3.size()
);
I want to be able to call simultaneously something like this in javascript:
classInstance.room.get('criteria');
classInstance.room('criteria').remove('criteria');
classInstance.room().update('criteria');
I have seen implemented something similar at shouldjs
should(10).be.a.Number();
(10).should.be.a.Number();
Updated
I have the following code:
function connectToDatabase() {
var server = orientDB(dbConfig.server);
var db = server.use(dbConfig.database);
db.on("endQuery", function onDbEndQuery() {
db.server.close();
});
return db;
}
var DbSet = function DbSet(name) {
return {
list: function list(where, select, order) {
where = where || true;
select = _.isString(select) || _.isArray(select) ? select : '*';
order = _.isString(order) || _.isArray(order) ? order : 'rid';
return connectToDatabase()
.select(select)
.from(name)
.where(where)
.order(order)
.all();
},
get: function get(where, select) {
where = where || true;
select = _.isString(select) || _.isArray(select) ? select : '*';
return connectToDatabase()
.select(select)
.from(name)
.where(where)
.all()
.then(function onResults(results) {
if (results.length > 1) {
throw new Error('multiple results');
}
return results[0];
});
},
create: function create(record) {
return connectToDatabase()
.insert()
.into(name)
.set(record)
.one();
},
update: function update(where, changes) {
where = where || true;
return connectToDatabase()
.update(name)
.set(changes)
.where(where)
.scalar();
},
remove: function remove(where) {
where = where || true;
return connectToDatabase()
.delete('VERTEX', name)
.where(where)
.scalar();
}
};
};
var db = function getDb() {
return {
room: new DbSet('Room'),
invitation: new DbSet('Invitation'),
participant: new DbSet('Participant'),
};
};
module.exports = db();
And I want to change the code be able to execute the following code:
var db=require('path/to/database');
var room = db.room.get({name:'room 1'});
var sameRoom = db.room({name:'room 1'}).get();
db.room.create({name:'second room'});
db.room({name:'second room'}).create();
//same for methods list and delete
var room = db.room.list({status:'active'});
var sameRooms = db.room({status:'active'}).list();
db.room.update({name:'second room'},{status:'inactive'});
db.room({name:'second room'}).update({status:'inactive'});
I want to be able to execute the same code for Invitation and Participant too.
We need more information as to what those functions do, but this code presents those features.
Klass = function () {};
Klass.prototype.room = function () {
....
return {
get: function () {...},
remove: function () {...},
update: function () {...}
}
};
Klass.prototype.room.get = function () {...};
classInstance = new Klass();
I want to remove and add an element from an array which is nested in a ko.observable object. I'm using the ko.mapping utility to map json data to my viewmodel. Inside the json data i have an array and it is this array that i want to remove and add an element from.
The add and remove functions are call from HTML bindings.
See my current code for doing this. It is not elegant at all, i know that, that is why i'm asking for help. How do i do see smarter?
function BaseViewModel() {
var self = this;
self.newItem = null;
self.selectedItem = ko.observable();
self.getNewItem = function () {
return self.newCleanItem(self.newItem);
}
self.read = function (search, callback) {
self.baseService.read(search, callback);
}
self.readCallback = function (data) {
if (self.newItem == null)
self.newItem = data;
self.selectedItem(data);
showInputContainer();
}
self.addLog = function () {
var item = new self.getNewItem();
var newItem = item.tLogs[0];
var currentSelectedItem = ko.mapping.toJS(self.selectedItem);
currentSelectedItem.tLogs.push(newItem);
self.selectedItem(currentSelectedItem);
showInputContainer(activeTab);
};
self.removeLog = function (item) {
var currentSelectedItem = ko.mapping.toJS(self.selectedItem);
currentSelectedItem.tLogs.pop(item);
vm.selectedItem(currentSelectedItem);
showInputContainer();
}
self.newCleanItem = function (data) {
for (var d in data) {
if (Object.prototype.toString.call(data[d]) === '[object Array]') {
var array = data[d];
for (var item in array) {
if (framework.baseFunctions().isNumeric(item)) {
for (var i in array[item]) {
array[i] = "";
}
}
}
data[d] = array;
}
else {
data[d] = "";
}
}
return data;
}
}
My jsondata could look that this:
jsondata = {
caseName: "test",
caseDescription: "This is a test",
tLogs: [
{
name: "log1",
date: "2013-03-19"
},
{
name: "log2",
date: "2013-02-02"
}
]
}