how to fetch _id data in loopback - node.js

My Database is arangodb. What i want to do is : I have data like this:
_id:authModel/1209597
_key:1209597
{
email: 'abc#gmail.com',
password: 'password',
subuser_ids:[ '811289', '1209611' ],
id: '1209597'
}
_id:authModel/811289
_key:811289
{
email: 'pqr#gmail.com',
password: 'password',
id: '811289'
}
actually i need to fetch data which is the ids in subuser_ids array, ie the subuser_ids contain 2 ids. I need to fetch the data that the subuser_id hold. suppose subuser_id is "811289" that is _id="811289" i need to fetch that data. am using arangodb and loopback. also i write an remote method to accesss that data. What i have is :
model.js
var server = require("../../server/server");
module.exports = function (Authmodel) {
Authmodel.on("attached", function () {
Authmodel.getApp(function (err, app) {
Authmodel.getSubUsers = function (params, cb) {
var result = [];
params.forEach(function (id) {
app.models.authModel.findOne({ "_id": id }, function (err, r) {
console.log("err", err);
console.log("r", r);
result.push(r);
});
})
cb(null, result);
};
});
});
Authmodel.remoteMethod('getSubUsers', {
accepts: { arg: 'params', type: 'array' },
returns: { arg: 'result', type: 'array' }
});
};
i got the log in the result console but that data is not correct.
How can i solve this issue? i need to fetch all subuser_ids data. any help will really appreciable and helpfull.

Related

How to read an image and text at the same time in Loopback/NodeJs

I am doing a remote method with Loopback to show some text and display an image. I am getting the path of the image and the fields by an sql query and data is showed correctly. What I want to do is to transform the path showed in the result to display the image itself.
This is my remote method so far :
cm_comediens.getprofile1 = function (options, cb) {
const token = options && options.accessToken;
const userId = token && token.userId;
var ds = app.datasources.mydb;
var sql = "SELECT comedien_perso_nom,comedien_perso_prenom,nationalite,photoscomedien.path FROM cm_comediens INNER JOIN photoscomedien ON cm_comediens.id_comedien=photoscomedien.id_comedien WHERE cm_comediens.id_comedien IN ( SELECT id_comedien FROM (SELECT id_comedien FROM cm_comediens WHERE id_utilisateur= '" + userId + "') as MakeitWork) AND photoscomedien.photo_profile=1 ";
ds.connector.execute(sql, [], function (err, cm_comedienss) {
if(err) {console.error(err);}
cb(err, cm_comedienss);
});
}
cm_comediens.remoteMethod(
'getprofile1', {
http: {verb: 'GET'},
description: 'Get Comediens infos',
accepts: [{arg: "options","type": "object","http": "optionsFromRequest"},],
returns: {arg: 'data',type: ['cm_comediens'],root: true,}
}
);
This is what I am getting so far and what I want to do exactly is to change the path to an image
Result
I tried to add the fs.readfile but weird result showed up. I changed the remote method as follows :
ds.connector.execute(sql, [], function (err, cm_comedienss) {
fs.readFile(cm_comedienss[0].path, function(err, cm_comedienss) {
if(err) {console.error(err);}
cb(err, cm_comedienss);
});
});
}
This is the result I got after adding the readfile :
after adding fs.readfile
The remoting metadata for your new method are describing the return value as a JSON data. The actual value is Buffer, which is converted by LoopBack to the value you shown on your screenshot.
{
"$type": "base64"
"$data": "(base64-encoded data of your image)"
}
If you want your API to return image, you need to make two changes:
tell LoopBack to set a different Content-Type header, e.g. image/png
tell LoopBack to treat the Buffer value as the raw response body
cm_comediens.getprofile1 = function (options, cb) {
ds.connector.execute(sql, [], function (err, found) {
if (err) return cb(err);
fs.readFile(found[0].path, function(err, image) {
if(err) return cb(err);
cb(null, image, 'image/png');
});
});
};
cm_comediens('getprofile1', {
http: {verb: 'GET'},
description: 'Get Comediens infos',
accepts: [
{arg: "options","type": "object","http": "optionsFromRequest"},
],
returns: [
{ arg: 'body', type: 'file', root: true },
{ arg: 'Content-Type', type: 'string', http: { target: 'header' } },
],
});

node.js mongoose subfield in a document

I have been working with node.js and mongoose for sometime and I am hitting a wall. I have a database with 20,000 documents and when i search the database from the cli it works fine.
db.Tickets.find({ "Customers.Customer.CustomerID" : '123123123' })
This returns 256 results
Schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Define collection and schema for Ticket
var Ticket = new Schema({
UserName: {
type: String
},
Status: {
type: String
},
TicketNumber: {
type: Number
},
Name: {
type: String
},
Description: {
type: String
},
TicketTypeName: {
type: String
},
DueDate: {
type: Date
},
MapCollectDate : {
type: Date
},
NumberofUsersAffected : {
type: Number
},
DNNumber : {
type : String
},
RevisionDate : {
type : Date
},
CommercialImpact : {
type: String
},
Customers :[{
Customer: [{
CustomerID: Number,
CustomerName: String
}]
}],
Although if I test this in node.js using mongoose. I can't get it to return anything
I have a generic search that works
Ticket.find(function (err, tickets){
But can't get the specific search to work.
I am Connecting to Mongo
const config = require('./db');
//const Course = require('./models/Course');
//const CourseRoute = require('./routes/CourseRoute');
const Ticket = require('./models/Ticket');
const TicketRoute = require('./routes/TicketRoute');
const PORT = 4000;
mongoose.connect(config.DB).then(
() => {console.log('Connected to MongoDB') },
err => { console.log('Error connecting to MongoDB' +err)
});
Output of the log
Your node js server is running on PORT: 4000
Connected to MongoDB
Connected to MySQL
My Route End point
router.route('/').get(function (req, res) {
Ticket.find({ "Customers.Customer.CustomerID" : global.auth_username }, function(err, ticket) {
if(err){
console.log(err);
}
else {
res.json(tickets);
}
});
});
Also tried without the variable
router.route('/').get(function (req, res) {
Ticket.find({ "Customers.Customer.CustomerID" : "123123123" }, function(err, ticket) {
if(err){
console.log(err);
}
else {
res.json(tickets);
}
});
});
I had the same issue when I forgot to connect to Mongoose before running query
mongoose.connect(MONGO_URL, mongoOptions)
.then(() => {
// do your thing here
})
You had over a year to figured this out, and I am sure that you did so, but either way it seems that you have a typo in your code. The callback parameter is named ticket - function(err, ticket) {, whereas you are logging tickets - res.json(tickets);. In the generic test you correctly wrote tickets - Ticket.find(function (err, tickets){, which is probably why it worked.
The takeaway lesson here is - use debugging tools instead of logging, makes it easier to catch such problems.
Also, it would be appropriate to answer your own question once you've figured it out. But given that this is probably completely useless, you might as well delete it. Cheers!

Mongoose Subdocument will not update

I am having trouble figuring out if I designed the schema correctly because I am receiving a 500 error when attempting to PATCH changes of the roles property from a profile. (Note: The 500 error just responds with an empty {}, so it isn't really informative)
Below is the profile schema:
var ProfileSchema = new Schema({
name: {
type: String,
required: true
},
roles: [{
application: {
type: Schema.Types.ObjectId,
required: true,
ref: 'Application'
},
role: {
type: String,
required: true,
enum: [ 'admin', 'author', 'publisher' ]
}
}]
});
Each profile has a role for an application, and when I send the request to the controller action 'update', it fails:
profile update controller:
// Updates an existing Profile in the DB
export function update(req, res) {
try {
if (req.body._id) {
delete req.body._id;
}
console.log('ENDPOINT HIT...');
console.log(`REQUEST PARAM ID: ${req.params.id}`);
console.log('REQUEST BODY:');
console.log(req.body);
console.log('ENTIRE REQUEST: ');
return Profile.findByIdAsync(req.params.id)
.then(handleEntityNotFound(res))
.then(saveUpdates(req.body))
.then(respondWithResult(res))
.catch(handleError(res));
} catch(ex) {
console.error('FAILED TO UPDATE PROFILE');
return handleError(res);
}
}
I made sure that the id and body was being sent properly, and I am hitting the end point.
This is an example of the request body JSON:
{
_id: 57e58ad2781fd340563e29ff,
__updated: Thu Oct 27 2016 15:41:12 GMT-0400 (EDT),
__created: Fri Sep 23 2016 16:04:34 GMT-0400 (EDT),
name: 'test',
__v: 11,
roles:[
{ application: 57b70937c4b9fe460a235375,
role: 'admin',
_id: 58125858a36bd76d8111ba16 },
{ application: 581b299f0145b48adf8f57bd,
role: 'publisher',
_id: 581b481898eefb19ed8a73ee }
]
}
When I try to find the Profile by Id, the promise chain goes straight to the catch(handleError(res)); part of the code and shows an empty object in my console.
My handle error function:
function handleError(res, statusCode) {
console.error('HANDLE PROFILE ERROR: ', statusCode);
statusCode = statusCode || 500;
return function(err) {
console.error('PROFILE ERROR:');
console.error(JSON.stringify(err, null, 2));
res.status(statusCode).send(err);
};
}
UPDATE
I am realizing the code is breaking when it hits my saveUpdates function (Note: I am using lodash):
function saveUpdates(updates) {
/// the code is fine here ///
return function(entity) {
/// once it enters in here, is where it begins to break ///
var updated = _.merge(entity, updates);
if(updated.roles.length != updates.roles.length) {
updated.roles = updates.roles;
}
for(var i in updates.roles) {
updated.roles.set(i, updates.roles[i]);
}
return updated.saveAsync()
.then(updated => {
return updated;
});
};
}
Lesson learned: Read Documentation properly.
Since I am using bluebird promises for this application, I forgot to use .spread() within my saveUpdates() callback function.
Solution:
function saveUpdates(updates) {
return function(entity) {
var updated = _.merge(entity, updates);
if(updated.roles.length != updates.roles.length) {
updated.roles = updates.roles;
}
for(var i in updates.roles) {
updated.roles.set(i, updates.roles[i]);
}
return updated.saveAsync()
// use `.spread()` and not `.then()` //
.spread(updated => {
return updated;
});
};
}
I want to thank the following SOA that led to this conclusion: https://stackoverflow.com/a/25799076/5994486
Also, here is the link to the bluebird documentation in case anyone was curious on .spread(): http://bluebirdjs.com/docs/api/spread.html

Fetching from Model has not supply the defaults

In my app, I am fetching the data from /home -by home Model. the Model contains the defaults object. But while i fetch the data, I am not able to see the default object in the model.
here is my model :
define(['backbone'], function(Backbone){
"use strict";
socialApp = window.socialApp || {};
socialApp.homeModel = Backbone.Model.extend({
url: "/home",
defaults:{
"category":"Level-1"
}
});
return socialApp.homeModel;
});
here is my view.js :
socialApp.homeView = Backbone.Marionette.ItemView.extend({
tagName:'div',
initialize:function () {
var that = this;
this.model.fetch().done(function(data){
that.render(data) // i am fetching here
});
},
render: function (data) {
console.log(data) //there is no defaults object here...
this.$el.html(homeTemp(data));
}
});
What is wrong here? I am using Nodejs as a server.
here is the console what i am getting:
{
__v: 0
_id: "5416ce23fc0c41ec0f03f672"
email: "afzil#gmail.com"
firstName: "Mohamed"
lastName: "Afzil"
password: "afzil"
username: "afzil"
}
thanks in adavnce.
As i can see in promise 'done' callback you have only fetch results, not model.
please modify your initialize function to this:
initialize: function () {
var that = this;
this.model.fetch({
success: function(model){
that.render(model.toJSON());
}
});
}

Node.JS cradle and couchDB assistance

I am a noob with Node.JS.
I am using CouchDB and Cradle.
In couchDB I have a database named 'test' and inside it I have a document named 'exercise'.
The document has 2 fields: "FullName" and "Age".
The code in order to save the data is as follows:
var cradle = require('cradle');
var connection = new(cradle.Connection)('http://127.0.0.1', 5984, {
auth: { username: 'toto_finish', password: 'password' }
});
var db = connection.database('test');
db.save('exercise', {
FullName: param_name, Age: param_age
}, function (err, res) {
if (err) {
// Handle error
response += ' SAVE ERROR: Could not save record!!\n';
} else {
// Handle success
response += ' SUCESSFUL SAVE: The record was saved in CouchDB!\n';
}
http_res.end(response);
});
this code works well and it saves the data to the CouchDB.
My problem is when I want to read the data.
The code that I wrote is:
var cradle = require('cradle');
var connection = new(cradle.Connection)('http://127.0.0.1', 5984, {
auth: { username: 'toto_finish', password: 'password' }
});
var db = connection.database('test');
db.view('exercise/all', {descending: true}, function(err, res)
{
console.log(res);
res.forEach(function (row) {
response = 'FullName: ' + row.FullName + '\n Age: ' + row.Age + '\n';
});
});
http_res.end(response);
when I am trying to print response, response is empty and I don't know what I am doing wrong. I know that it does not go inside the forEach loop but I don't understand why.
the console output is:
[ { id: 'exercise',
key: null,
value:
{ _id: 'exercise',
_rev: '1-7042e6f49a3156d2099e8ccb3cc7d937',
FullName: 'Toto Finish',
Age: '30' } } ]
Thanks in advance for any response or answer.
Try moving the http_res.send() call inside the callback provided to db.view - the anonymous function( err, res ) { }.
I'm not sure however about the .forEach statement, you'll only get the last value from your query in the response variable, you should look into that as well.
spotirca is right
The db.view function is async so http_res.end(response) gets called before the view returns any data.
You can prove this by returning the date in both the console.log and http_res.end
console.log(res, new Date())
and
http_res.end(response, new Date());
The http response will have the earlier date/Time.

Resources