sails.js preload action in controller - node.js

I need a help in sails.js framework.i am developing the website in nodejs and sails.js framework.
is there any way to call preload action in each controller.(for ex: the controller calling time load this action).each controller having different pre load action.
Please any one suggest to me.how can i create this way or any other way.
Thanks to all.

use a service:
/service/mypre.js:
exports.first = function(req,res,cb) {
// here add you code
cb();
}
in Controller:
module.exports = {
index: function(req,res) {
sails.mypre.first(req,res, function(){
// Do other things...
});
}
}
And you may add a callback to make sure, your mypre() is done completely.

Related

Override NestJS route within controller

I want to completely override a controller route. E. g:
#Controller('shipments')
export class ShipmentsController {
#Post('/create')
async find(): Promise<Activities> {
return service.find()
}
}
In order to make a request to the previous example, The URL will be: http://localhost:8080/shipments/create
I want to change that URL without moving the controller to another class. For example, I want the URL for that specific function to be http://localhost:8080/whatever/i/want.
Is this possible?
This is not possible, and goes against the ideas of the framework of having easy to configure routes with structure and uniformity. If you want a route like that, you can use express on it;s own, or technically add the route in the bootstrap file like so
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.getHttpServer().get('/whatever/you/want', (req, res, next) => {});
await app.listen(3000);
}
But now you don't have (easy) access to services, testing this is a pain, and generally it's confusing, not to mention no use of any Nest enhancers like interceptors or pipes.

How to make Sails.js app listen to events of ethereum blokchain to perform CRUD on persistence layer

I have a smart contract deployed on Ethereum blockchain and it emits some event with necessary data.
I have a sails.js application which needs to listen to this event.
Roughly, the javascript code looks like -
var event = contract.myEvent();
event.watch((err, res) => {
console.log(res); // event response
// API call to DB for persistence
});
My question is where should this code sit in sails.js application as sails.js follows MVC, is it a good idea to use sails.js ?
Suggestions about design pattern are appreciated.
This code should be excuted as a Service at the application start time.
for example you can create a file named EventsService.js :
let event = contract.myEvent();
exports.start = function () {
event.watch((err, res) => {
console.log(res); // event response
// API call to DB for persistence
});
}
and then you can start the service like this: (from the app.js file)
const eventService = require('path/to/EventService.js');
eventService.start();

How to login a user on a REST API using restful-keystone

I am trying to expose a model created with keystonejs over a REST API using restful-keystone. The API should allow to create a new user or to retrieve the information of a user. This is my code
var beforeRetrieve = function (req, res,next) {
console.log(req.user);
next();
};
restful.expose({
User: {
show : ["_id","name", "email", ],
methods: ["retrieve", "create"]
}
}).before({
User: {
retrieve: [beforeRetrieve, middleware.requireUser],
create: [],
}
}).start();
The code is working but I am getting confused. console.log(req.user); is printing undefined which is logic. But how can I make it work and print the user initiating the request? Shall I include the user cookies in the request? Shall I create another API that allow the user to login and get the cookies/token? Is there already one in keystone? Can you please give me some idea on how to achieve that? My ideal case is to allow anyone to create a new user. By creating the new user a token should be returned and used in the future to identify the user. I am not sure how shall I proceed, can you please help me with some ideas, I am really confused
Please kindly check if you are using Keystone v4.0 but restful-keystone is supporting Keystone v0.3. For Keystone you can expose REST API without any additional modules.
For example you can edit routes/index.js to add a route:
// Setup Route Bindings
exports = module.exports = function (app) {
// Views
app.get('/', routes.views.index);
// API
app.get('/api/user', routes.api.user.get);
};
And then create route/api/user.js to capture the REST reqeust:
var keystone = require('keystone');
var cdf = keystone.list('User');
exports.get = function(req, res) {
...
}
But for user model, there is a ready-made REST API, but this requires Admin Permission:
http://server:port/keystone/api/users

Angular Controllers and Services

I'm pretty new to web dev and AngularJS. I'm trying to figure out how to use services and I'm following this tutorial: http://scotch.io/bar-talk/setting-up-a-mean-stack-single-page-application
How does the service connect with the controller? Is this done implicitly? I understand that you can inject the service into the controller, but how is it being done in the tutorial?
You inject your service into your controller. Like this. The reason behind services are that you want to keep your controller as 'skinny' as possible. All heavy logic/requests should be outsourced to the service.
app.service('myService', function(){
this.name = 'Tyler';
}
app.controller('myCtrl', function($scope, myService){
$scope.name = myService.name;
}
Another benefit of using a service is that you could inject that service into more than one controller. A good example is if you had a service that made a HTTP request. Instead of recreating the same code in every controller to make the request, you could simply create a service that did the request and inject that service into every controller you needed that functionality.
edit: To answer your question. You need to be sure to place the service in the controller on the same 'module'. Meaning. In your HTML you have something like this.
<body ng-app="myApp">
That's telling the whole BODY that whatever is nested inside it belongs to the 'myAPP' app. Then you usually have an app.js file that has something like this.
var app = angular.module('myApp', []);
Notice that the angular.module takes two parameters. You're telling angular to create a new app called 'myApp' (which coincides with your HTML).
Then in your controller, service, directive files you'll have something like this at the top.
var app = angular.module('myApp');
Notice this one is only taking one parameter, the name of the app. You're telling angular that instead of creating a new app, you're going and 'getting' the one you already build. You'll then stick your controllers, directives, services on this app and as long as things are on the same app, you'll be able to inject them.
Another EDIT to your comment.
In the tutorial they're doing it a little weird. They're creating new modules for every controller, service, etc. It's not bad, just different. Doing it this way confuses me so I just prefer to stick everything under one module. In the tutorial this is the line that's gluing it all together.
// public/js/app.js
angular.module('sampleApp', ['ngRoute', 'appRoutes', 'MainCtrl', 'NerdCtrl', 'NerdService', 'GeekCtrl', 'GeekService']);
They have a sampleApp then all there other modules they build are being injected into the main sample app.
a service means to be accesible from all controllers, a service is a constructor, every controller can read or write in a service, in order to use a service you must call a service in this way:
var app = angular.module('myApp', []);
app.service('sharedProperties', function() {
var stringValue = 'test string value';
var objectValue = {
data: 'test object value'
};
return {
getString: function() {
return stringValue;
},
setString: function(value) {
stringValue = value;
},
getObject: function() {
return objectValue;
}
}
});
app.controller('myController1', function($scope, sharedProperties) {
$scope.setOnController1 = function(sharedPoperties){
$scope.stringValue = sharedProperties.getString();
$scope.objectValue = sharedProperties.getObject().data;
}
});
app.controller('myController2', function($scope, sharedProperties) {
$scope.stringValue = sharedProperties.getString;
$scope.objectValue = sharedProperties.getObject();
$scope.setString = function(newValue) {
$scope.objectValue.data = newValue;
sharedProperties.setString(newValue);
//some code to set values on screen at controller1
};
});
Here is the JS FIDDLE
http://jsfiddle.net/b2fCE/228/

Is it OK to add data to the response object in a middleware module in Express.js?

Here's the basic setup. I'm trying to create a simple middleware component that would allow me to easily pass data from my route directly to my javascript in the client side. (Very similiar to the Gon gem in ruby). The way I'm doing it is by having a module that looks like this:
module.exports = function(){
return function(req,res,next){
var app = req.app;
if(typeof(app) == 'undefined'){
var err = new Error("The JShare module requires express");
next(err);
return;
}
res.jshare = {};
app.dynamicHelpers({
includeJShare: function(req,res){
if(typeof(res.jshare) === 'undefined'){
return "";
}
return function(){
return '<script type="text/javascript">window.jshare=' + JSON.stringify(res.jshare) + '</script>';
}
}
});
next();
};
}
Then, in my route I can do this:
exports.index = function(req, res){
res.jshare.person = {firstName : "Alex"};
res.render('index', { title: 'Express' })
};
Finally in the layout.jade:
!{includeJShare()}
What that does is in outputs a line of javascript on the client that creates the exact JSON object that was created server side.
Here's the question; it all works as expected, but being new to Express and Node.js in general, I was just curious if attaching properties onto the response object is OK, or is there something wrong with doing it that I'm simply overlooking? For some reason it doesn't pass my "smell test" but I'm not sure why.....
I know this is an old thread, but there is something else to add to this topic.
Express has a response.locals object which is meant for this purpose - extending the response from middleware to make it available to views.
You could add a property directly to the response object, and as #hasanyasin indicated, is how JavaScript is designed. But Express, more specifically, has a particular way they prefer we do it.
This may be new in express 3.x, not sure. Perhaps it didn't exist when this question was asked.
For details, see
http://expressjs.com/en/api.html#res.locals
There is also an app.locals for objects which don't vary from request to request (or response to response I suppose).
http://expressjs.com/en/api.html#app.locals
See also: req.locals vs. res.locals vs. res.data vs. req.data vs. app.locals in Express middleware
It is perfectly OK. It is how JavaScript is designed. Only thing you should be careful is to not accidentally overriding already existing properties or being overridden by others. To be safer, instead of adding everything directly to req/res objects, you might consider going a level deeper:
res.mydata={}
res.mydata.person= ...
Like that.
Use res.locals for including custom variables in your response object.

Resources