customize CRUD operation in loopback js - node.js

i am new to loopback js trying to create remote method Create,Read,update and delete operation.
i have created a model name class and now i want to write the crud operation in my project file
models/class.js file.
'use strict';
module.exports = function(Class) {
};
I have no idea how to do it , read docs but does not clearify things if anyone can give example to write CRUD operation would be better understanding. (Using loopback 3 for practice.)

To create a custom method for a model, you need to do two things:
1/ Create the method within your model like this:
module.exports = function (Mymodel) {
Mymodel.myCustomMethod = function (req, res, cb) {
// method body
}
}
2/ To declare the remote to your model, so it can be exposed
module.exports = function (Mymodel) {
/* custom methods, hooks, ... */
Mymodel.remoteMethod(
'myCustomMethod', {
http: {
path: '/myCustomMethod',
verb: 'post' // it could also be 'post', 'put', 'delete'
},
accepts: {
arg: 'data',
type: 'object', // accepting an object in the body
'http': {
source: 'body' // Reading the body of the request. It could also be 'req' to read the req url for parameters.
}
},
returns: {
type: 'object', // Returns an object to the front
root: true
}
}
)
}
This is an example for a 'post' remote method. A 'put' remote method will look exactly the same, except for the keyword 'put' instead of 'post'.
For a 'get' or 'delete' requests, only the request url will be read, so the remote method should contain:
http: { path: '/myCustomMethod/:projectId', verb: 'get' },
accepts: { arg: 'projectId', type: 'number' },
With projectId the name of a property given in the URL, and number being the type of projectId.

Related

Hapjs Route Prerequisite is executed and route is always returning 404

I am building a web application using Hapijs. I am using route prerequisites to do something before the route handler is executed.
This is my route
server.route([
{
method: 'GET',
path: '/users',
pre: {
assign: 'Test',
method: async (request, h) => {
console.log('Pre route is executed.');
return "test data";
}
},
handler: userController.getUsers,
options: {
auth: 'jwt-auth'
}
},
])
But when I execute the code, it is not executing the pre route method. When the pre route handler is included, it is always returning 404 not found response. Without it, it is working. What is wrong with my code and how can I fix it?
According to the "pre documentation", "pre" should be placed inside of the "options" property and should be an array
Here is an example how what it should look like for your code:
server.route([
{
method: 'GET',
path: '/users',
handler: userController.getUsers,
options: {
auth: 'jwt-auth',
pre: [{
assign: 'Test',
method: async (request, h) => {
console.log('Pre route is executed.');
return "test data";
}
}]
}
},
])
You can get access to your "pre" data in the handler like this: const data = req.pre.Test

Set params on request when testing hapi routes

I am currently writing some tests for our hapi routes. The route I want to test looks like that:
server.route(
{
method: 'POST',
path: '/',
options: {
tags: ['api'],
cors: true,
handler: async (req: Hapi.Request | any, h: Hapi.ResponseObject) => {
if (!req.params.userId) {
throw Boom.badRequest();
}
return 200;
}
}});
So my test looks like this:
it('should return 200', async () => {
const request : ServerInjectOptions = {
url: '/user',
method: 'POST',
payload: {
email: 'e#email.de',
password: 'secred',
firstname: 'John',
lastname: 'Doe'
},
app: {}
};
const response = await server.inject(request);
expect(response.statusCode).toEqual(200);
});
As you can see the route expects a param in the params array with the name userId but i am not able to set the parameter on the ServerInjectOptions object. The error I get is that the property does not exist on the ServerInjectOptions type.
Is there any other way i can set the params array? I didn`t find something in the docs maybe i missed it and someone can tell me where to find it.
Thanks in advance
For the route I believe you add the name of the parameter to the path like so:
server.route(
{
method: 'POST',
path: '/:userId',
//
}});
And for the test you should be able to add your parameter to the url option:
const request : ServerInjectOptions = {
url: '/user/parameterYouNeedToAdd',
//
};
Or if the parameter is a variable:
const request : ServerInjectOptions = {
url: '/user/' + parameterYouNeedToAdd,
//
};

How to parse querystring parameter from URL in Fastify server?

I am a totally new to fastify but I have a fastify server running. I want to parse query string such as:
http://fake.com/?user=123&name=ali
I want to get "user" and "name" values from the URL above. My current code is like this:
fastify.route({
method: 'GET',
url: '/',
handler: async (request, reply) => getCompanyUsers(request, reply, services)
});
I want to get values of "user" and "name" and then pass the values to getCompanyUsers function.
Any help is appreciated.
Thanks
You can access the querystring using request.query
You can look at the official documentation here
https://github.com/fastify/fastify/blob/main/docs/Reference/Request.md
fastify.route({
method: 'GET',
url: '/',
schema: {
// request needs to have a querystring with a `name` parameter
querystring: {
name: { type: 'string' }
}
},
handler: async (request, reply) => {
// here you will get request.query if your schema validate
}
})

Object property key is different within req.body than client-side (Express)

I'm a bit of a noob working on my first CRUD application (dream journal) using Node, Express, and MongoDB/Mongoose.
I'm creating a simple object based on a few user form inputs and then submitting a post request to the server, which in turn calls Mongoose.save().
The object I'm creating on the client side, however, is slightly different than the one that is being received by the server, and I'm at a complete loss as to why.
First I'm getting some values from a form and putting them in an object:
// within button click event handler
var dreamText = $('#dream-text').val().trim();
var dreamTags = ["tag 1", "tag 2", "tag 3"]; // for debugging
var dreamLucid = $('#dream-lucid').val() == 'Yes' ? true : false;
var dreamDate = $('#dream-date').val();
var dream = {
userID: 'test',
text: dreamText,
tags: dreamTags,
isLucid: dreamLucid,
dateCreated: dreamDate
};
Here a console.log of dream shows everything as it should be:
Object {userID: "test", text: "sample text", tags: Array[3], isLucid: false, dateCreated: "2016-08-08"}
From there I'm submitting a POST request with the dream object:
$.ajax({
type: 'POST',
url: '/new',
data: dream,
success: function(data){
console.log('dream saved');
}
});
Now on the server side, with Express and Mongoose, I'm attempting to save the object to a DB:
router.post('/', urlencodedParser, function(req, res) {
console.log(req.body);
var newDream = Dream(req.body).save(function(err, data){
if (err) {
throw error;
}
});
});
All the properties except tags are saving correctly, and a console.log of req.body yields:
{ userID: 'test',
text: 'sample text',
'tags[]': [ 'tag 1', 'tag 2', 'tag 3' ],
isLucid: 'false',
dateCreated: '2016-08-08' }
Any idea why the tags property on the client side is becoming 'tags[ ]' when it gets passed through the POST request?
I've tried both tags: Array and tags: [String] in my Mongoose Model, but the problem seems to be occurring before I ever call Mongoose.save.
By default, $.ajax() encodes a POST operation as application/x-www-form-urlencoded which does different things with arrays. You probably just want to send JSON so you can receive JSON on the server.
You can cause that to happen by manually turning your data into JSON and setting the content type appropriately:
$.ajax({
type: 'POST',
url: '/new',
data: JSON.stringify(dream),
contentType: "application/json",
success: function(data){
console.log('dream saved');
}
});
Then, you may also have to parse the JSON on the server side of things, either manually for this request or with some middleware like bodyParser.json().

Can't call success function

I'm developing a Backbone Node.js with Express.js app. I'm trying to trigger a function after receiving a response from my server like the code bellow:
mainView.js
...
user: null,
initialize: function () {
_.bindAll(this, 'registerSuccess', 'loginSuccess');
this.user = new userModel();
}
registerSuccess: function () {
this.user.auth({
success: this.loginSuccess
});
});
loginSuccess: function () {
console.log('loginSuccess');
}
userModel.js
...
, auth: function (options) {
$.ajax({
url: 'users/auth'
, type: 'post'
}, options);
})
app.js
var api = require('./routes/apiController');
app.post('/users/auth', api.userAuth);
apiController.js
exports.userAuth = function (req, res) {
return res.send( {
status: 200
});
}
I´m getting the response:
But it doesn't print the console.log('loginSuccess') sentence from this function.
There are two ways to call $.ajax:
jQuery.ajax(url, settings)
jQuery.ajax(settings)
In the first case, url must be a string and settings is an optional object; in the second case, settings is again an optional object. You're calling $.ajax with two objects:
auth: function (options) {
$.ajax({
url: 'users/auth'
, type: 'post'
}, options);
}
Since the first argument is not a string, $.ajax will use the second calling form and ignore options completely. You probably want to use _.extend to merge the arguments:
$.ajax(_({
url: 'users/auth'
, type: 'post'
}).extend(options));
Or _.defaults if you want to avoid accidentally overwriting url and type:
$.ajax(_({
url: 'users/auth'
, type: 'post'
}).defaults(options));
Or, since you only have two things, just stuff them in manually:
options = _(options).clone(); // Avoid accidentally messing with the argument.
options.url = 'users/auth';
options.type = 'post';
$.ajax(options);

Resources