Below function I copy it from surveyjs-nodejs repository and looking to achieve this similar into mysql.
function getObjectFromStorage(tableName, callback) {
db.any("SELECT * FROM " + tableName).then(function(result) {
var objects = {};
(result || []).forEach(function(item) {
objects[item.id] = item;
});
callback(objects);
});
}
getObjectFromStorage("surveys", function(objects) {
if (Object.keys(objects).length > 0) {
callback(objects);
} else {
callback(surveys);
}
});
how this .any works?
db
.one("INSERT INTO surveys (name, json) VALUES($1, $2) RETURNING *", [
name,
"{}"
])
.then(callback);
and how this RETURNING * use in mysql?
Thanks
Related
I'm trying to extract specific document fields from a mongodb collection (v 3.0.8 at MongoLab). The returned documents must fall within a date range. My goal is to extract specific fields from these documents. My nodejs code,
var query = {}, operator1 = {}, operator2 = {}, operator3 = {} ;
operator1.$gte = +startDate;
operator2.$lte = +endDate;
operator3.$ne = 'move';
query['xid'] = 1; // Problem here?
query['date'] = Object.assign(operator1, operator2);
query['type'] = operator3;
console.log(query);
MongoClient.connect(connection, function(err, db) {
if(err){
res.send(err);
} else {
db.collection('jbone')
.find(query)
.toArray(function(err, result){
console.log(err);
res.json(result);
});
};
});
If I opt to return all fields in the date range, the query works fine. If I select only field xid I get no results. My query object looks sensible according to the docs. console.log(err) gives:
{ xid: 1,
date: { '$gte': 20160101, '$lte': 20160107 },
type: { '$ne': 'move' } }
null
null is the err.
Can anyone help me understand what I'm doing wrong?
Or point me to another similar SO questions with an answer?
Thanks
To select the specific field could be done as below
.find(
{date: { '$gte': 20160101, '$lte': 20160107 }, type: { '$ne': 'move' }},
{ xid: 1} )
Sample codes as following.
query['date'] = Object.assign(operator1, operator2);
query['type'] = operator3;
db.collection('jbone')
.find(query, {xid: 1})
.toArray(function(err, result){
console.log(err);
res.json(result);
});
I'm trying to filter a JSON result from a SQLite query. The filter works when I use JSON directly, but it doesn't when I use the query from the service. Then, the $scope.arrayme just appears as empty.
Where is the error? Thank you!
This is the service:
getSubtipos: function() {
var query = "SELECT subtipos.idsubtipo, subtipos.tipos_idtipo, subtipos.nombre, subtipos.icon, subtipos.val FROM subtipos";
var arraySubtipos = [];
$cordovaSQLite.execute(db, query, []).then(function(res) {
if(res.rows.length > 0) {
for(var i = 0; i < res.rows.length; i++) {
arraySubtipos.push(res.rows.item(i));
}
} else {
console.log("No results found");
}
}, function (err) {
console.error("ERROR: " + err.message);
}).finally(function() {
arraySubtipos = JSON.stringify(arraySubtipos);
});
return arraySubtipos;
}
This is the controller:
.controller('MenuSubtiposCtrl', function($scope, $filter, miJson, $stateParams, $cordovaSQLite){
var arrayme = JSON.stringify(miJson.getSubtipos());
$scope.arrayme = $filter("filter")(JSON.parse(arrayme), {tipos_idtipo: $stateParams.foo});
})
And this is the state:
.state('app.menusubtipos', {
url: "/menusubtipos/:foo",
views: {
'menuContent': {
templateUrl: "templates/menuSubtipos.html",
controller: "MenuSubtiposCtrl"
}
}
})
There may be more problems than what I've immediately noticed, but I have have noticed that you're returning a variable within your getSubtipos function before it's set.
The $cordovaSQL.execute() function is an asyncronous function. As a result, you are returning arraySubtipos before it's set.
A better way to do this would be within getSubtipos to do the following:
var arraySubtipos = [];
return $q.when($cordovaSQLite.execute(db, query, [])
.then(function(res) {
if(res.rows.length > 0) {
for(var i = 0; i < res.rows.length; i++) {
arraySubtipos.push(res.rows.item(i));
}
} else {
console.log("No results found");
}
return JSON.stringify(arraySubtipos);
}));
// Then, within your controller, do the following:
.controller('MenuSubtiposCtrl', function($scope, $filter, miJson, $stateParams, $cordovaSQLite){
miJson.getSubtipos()
.then(function(arrayMe) {
// No need to stringify it again
$scope.arrayme = $filter("filter")(JSON.parse(arrayme), {tipos_idtipo: $stateParams.foo});
})
.catch(function(error) {
// Handle the error here
});
var arrayme = JSON.stringify(miJson.getSubtipos());
});
I'm also a little suspicious about your use of JSON.stringify and JSON.parse. It's likely that they're not needed, but without knowing the format of your data, I've left that as is.
Im using Parse REST API + AngularJS and Im trying to be able to get more than 1000 items per query. I try to develop a recursive function and concatenate each query until I get all the data. My problem is that I am not able to concatenate the JSON objects successfully. Here is what I have:
$scope.getAllItems = function(queryLimit, querySkip, query) {
$http({method : 'GET',
url : 'https://api.parse.com/1/classes/myClass',
headers: { 'X-Parse-Application-Id':'XXX','X-Parse-REST-API-Key':'YYY'},
params: {limit:queryLimit, skip:querySkip},
}).success(function(data, status) {
query.concat(data.results);
if(query.lenth == queryLimit) {
querySkip += queryLimit;
queryLimit += 100;
$scope.getAllItems(queryLimit, querySkip, query);
} else {
$scope.clients = query;
}
})
.error(function(data, status) {
alert("Error");
});
};
var myQuery = angular.toJson([]); //Am I creating an empty JSON Obj?
$scope.getAllItems(100,0, myQuery);
Is there any better solution to achieve this?
There may be better, more concise ideas available, but this is what I worked out for myself.
In my service ...
fetch : function(page, perpage) {
var query = // build the query
// the whole answer to your question might be this line:
query.limit(perpage).skip(page*perpage);
return query.find();
},
fetchCount : function() {
var query = // build the same query as above
return query.count();
},
In the controller...
$scope.page = 0; // the page we're on
$scope.perpage = 30; // objects per page
MyService.fetchCount().then(function(count) {
var pagesCount = Math.ceil(count / $scope.perpage);
$scope.pages = [];
// pages is just an array of ints to give the view page number buttons
for (var i=0; i<pagesCount; i++) { $scope.pages.push(i); }
fetch();
});
function fetch() {
return MyService.fetch($scope.page, $scope.perpage)).then(function(results) {
$scope.results = results;
});
}
// functions to do page navigation
$scope.nextPage = function() {
$scope.page += 1;
fetch();
};
$scope.prevPage = function() {
$scope.page -= 1;
fetch();
};
$scope.selectedPage = function(p) {
$scope.page = p;
fetch();
};
Then paging buttons and results in my view (bootstrap.css)...
<ul class="pagination">
<li ng-click="prevPage()" ng-class="(page==0)? 'disabled' : ''"><a>«</a></li>
<li ng-repeat="p in pages" ng-click="selectedPage(p)" ng-class="(page==$index)? 'active' : ''"><a>{{p+1}}</a></li>
<li ng-click="nextPage()" ng-class="(page>=pages.length-1)? 'disabled' : ''"><a>»</a></li>
</ul>
<ul><li ng-repeat="result in results"> ... </li></ul>
I fixed my recursive function and now its working. Here it is:
$scope.getAllItems = function(queryLimit, querySkip, query, first) {
$http({method : 'GET',
url : 'https://api.parse.com/1/classes/myClass',
headers: { 'X-Parse-Application-Id':'XXX','X-Parse-REST-API-Key':'YYY'},
params: {limit:queryLimit, skip:querySkip},
}).success(function(data, status) {
if(first) {
query = data.results;
first = !first;
if(query.length == queryLimit) {
querySkip += queryLimit;
$scope.getAllItems(queryLimit, querySkip, query, first);
} else {
$scope.clients = query;
}
} else {
var newQ = data.results;
for (var i = 0 ; i < newQ.length ; i++) {
query.push(newQ[i]);
}
if(query.length == queryLimit + querySkip) {
querySkip += queryLimit;
$scope.getAllItems(queryLimit, querySkip, query, first);
} else {
$scope.clients = query;
}
}
})
.error(function(data, status) {
alert("Error");
});
};
Simply pushed each element to my empty array, also I was mutating queryLimit instead of querySkip in order to iterate through all the elements.
I'm a little newbie in node.js + mysql + object oriented.
Following question here I would like the 'Content' object to use the values returned by a mysql query. What I'm doing now I find it is really redundant and possibly stupid as rows[0] itself is the object I want to use. Any better way for doing this? Or different approach if this is wrong also appreciated.
(I'm using binary uuid keys that must be hex-stringifyed again to send as resource response)
content.js:
function Content() {
this.id = '';
this.name = '';
this.domain = '';
}
Content.prototype.validate = function(path, queryParams) {
...
return true;
};
Content.prototype.whatever = function(apiVersion, params, callback) {
...
return callback(null, newParams);
};
mysql.js:
MySQLDb.SELECT_CONTENT_ID = "SELECT id, name, domain FROM content WHERE id = UNHEX(?)";
MySQLDb.prototype.findContentByID = function(id, callback) {
this.dbConnection.query(MySQLDb.SELECT_CONTENT_ID, [ id ],
function(err, rows, fields) {
var content = new Content();
if (rows.length > 0) {
var i = 0;
for (var key in rows[0]) {
if (rows[0].hasOwnProperty(key) && content.hasOwnProperty(key)) {
// BINARY(16) --> HEX string
if (fields[i].columnType === 254) {
content[key] = rows[0][key].toString('hex').toUpperCase();
} else {
content[key] = rows[0][key];
}
} else {
console.log('Column ' + key + ' out of sync on table "content"');
}
i += 1;
}
}
callback(err, content);
});
};
contentRes.js:
contentRes.GETWhatever = function(req, res) {
db.findContentByID(req.params.id, function onContent(err, content) {
if (err || !content.validate(req.path, req.query)) {
return res.send({});
}
content.whatever(req.query.apiVersion, req.query.d,
function onWhateverdone(err, params) {
if (err) {
return res.send({});
}
return res.send(params);
});
});
};
I think a lot of people would say you are doing it generally the right way even though it admittedly feels redundant.
It might feel a little cleaner if you refactored your code such that you could call the Content() constructor with an optional object, in this case rows[0] although if you were keeping it clean you wouldn't have access to the fields so you would take a different approach to the data type conversion - either by selecting the HEX representation in query or simply having your Content() know it needs to convert the id property.
Keeping it fairly simple (by which I mean ignoring making the constructor a bit more intelligent as well as any error detection or handling), you would have:
function Content(baseObj) {
this.id = (baseObj && baseObj.id) ? baseObj.id.toString('hex').toUpperCase() : '';
this.name = (baseObj && baseObj.name) ? baseObj.name : '';
this.domain = (baseObj && baseObj.domain) ? baseObj.domain : '';
}
Then you could do something like this:
MySQLDb.prototype.findContentByID = function(id, callback) {
this.dbConnection.query(MySQLDb.SELECT_CONTENT_ID, [ id ],
function(err, rows, fields) {
if (err) return callback(err,null);
return callback(err, new Content(rows[0]));
});
You 'could' also grab the rows[0] object directly, HEX the UUID more or less in situ and modify the __proto__ of the object, or under Harmony/ES6 use the setPrototypeOf() method.
MySQLDb.prototype.findContentByID = function(id, callback) {
this.dbConnection.query(MySQLDb.SELECT_CONTENT_ID, [ id ],
function(err, rows, fields) {
if (err) return callback(err,null);
var content = rows[0];
content.id = content.id.toString('hex').toUpperCase();
content.__proto__ = Content.prototype;
return callback(err, content);
});
Note, I said you 'could' do this. Reasonable people can differ on whether you 'should' do this. __proto__ is deprecated (although it works just fine in Node from what I have seen). If you take this general approach, I would probably suggest using setPrototypeOf(), and install a polyfill until you are otherwise running with ES6.
Just trying to give you a couple of other more terse ways to do this, given that I think the redundancy/verbosity of the first version is what you didn't like. Hope it helps.
I have Asp.Net Mvc4 application. In one Action method I have conditional process that return different json result as follows:
if(true)
{
return Json(new { count = cartItm.ProductCount, total = cartItm.TotalAmount });
}
else
{
return Json(new
{
thumb = item.ThumbnailPhoto,
productName = item.Name,
itemCount = cartItem.ProductCount,
itemTotal = cartItem.TotalAmount,
productTotal = cart.TotalAmount,
productCount = cart.CartItems.Sum(items=>items.ProductCount)
});
}
In jquery click event I can't define which json is returned. I write if condition as follows but get wrong result.
success: function (data) {
if (data.thumb != null) {//some operations }
else{//some operations }
Perhaps it is very easy problem, but I am new with json. Please help me.
thanks for reply
Check for "undefined" instead
success: function (data) {
if (typeof data.thumb !== "undefined") {//some operations }
else{//some operations }
Because item.ThumbnailPhoto on your server may be null. If this is the case, your check will fail.
Try this,
success: function (data) {
if (data && data.thumb) {//some operations }
else{//some operations }
}
The problem might be because you don't have data.thumbs in your first json, in your Action,
if(true)
{
return Json(new { flag = 1, count = cartItm.ProductCount, total = cartItm.TotalAmount });
}
else
{
return Json(new
{
flag = 2,
thumb = item.ThumbnailPhoto,
productName = item.Name,
itemCount = cartItem.ProductCount,
itemTotal = cartItem.TotalAmount,
productTotal = cart.TotalAmount,
productCount = cart.CartItems.Sum(items=>items.ProductCount)
});
}
in your view :
success: function (data) {
if (data.flag == 1) {//some operations }
elseif (data.flag == 2) {//some operations }
didnt check the code, but this must work.