I'm trying to store some log data for my models on create, update, delete calls. I want to store some data from the request along with some user data also in the request (using express.js).
In the hooks I have some modules for logging.
hooks: {
afterCreate: function (order, options, done) {
// How to get user data stored in express request.
return app.log.set('event', [{message: 'created', data: order, userId: 1}, done]);
}
}
...
The module just makes a record in a table. However it's the userId part I'm having trouble with. I'm using the passport module and it's stored in the request, so how can I get a user object (or any external object for that matter) into the model hooks?
I would like to avoid doing it in a controller or anywhere else as there could be some scripts or other commands that may also enter data.
I also encountered similar problems, which I myself resolved as follows:
First: I declared a Global (universal) hook:
module.exports = sequelize.addHook('beforeCreate',
function(model, options, done) {//hook 2
//handle what you want
//return app.log.set('event', [{message: 'created', data: order, userId: 1}, done]);
});
Then, Before calling model, use call hooks (beforeCreate, beforeBulkUpdate,...) and assigned param request
module.exports = {
CreateUser: function(req, res) {
User.beforeCreate(function(model, options, done) {//hook1
model.request = req;
});
User.create({
id: 1,
username: 'thanh9999',
password: '31231233123'
//ex.....
})
.then(function(success) {
//response success
}, function(err) {
//response error
});
}
};
order hooks called: hook declaration in model → hook 1 → hook 2`.
In addition, you also have to declare hooks for each model.
See more information here.
Related
This has been beating me up.
I have a vuex store, inside is a folder called "RyansBag" im using to test things.
I have two other folder, Alerts and Inventory. So the folder structure for each of these goes
store> Ryansbag/Alert/...
in my Inventory index.js file, we run a function to add an item to an inventory system.
async addInventory_Catalog({commit}, payload){
try{
const response = await this.$axios.put('Inventory/AddFromCatalogDefault', null, {
params:{
originalUPC: payload.upc,
clientID: payload.clientId,
saleprice: payload.sellPrice,
cost: payload.sellPrice,
Condition: payload.condition.conditionName,
Serial: payload.serialNumber,
Notes: payload.notes,
HoldDays: payload.holdDays,
}
});
console.log(response.data.success)
commit('RyansBag/Alerts/showAlerts', 'You have added a product!', {root: true})
return response.data;
} catch (error) { alert(error); console.log(error); }
},
Here we just pass the item down, and when it's done - commit the changes to our alert which is in store > RyansBag/Alerts.
You can see I tried to call it:
commit('RyansBag/Alerts/showAlerts', 'You have added a product!', {root: true})
My understanding was to simply state the commit is coming from this store as the root state...? But Im not sure if im supposed to register the commit in /Alerts as a global item somehow. ( https://vuex.vuejs.org/guide/modules.html#accessing-global-assets-in-namespaced-modules )
EDIT:::
Edit: There was no commit request in the action. added to post. Now however I get warning to not mutate state outside of state handlers..
Below is the mutation it's requesting to reach inside the alerts.
export const mutations = {
showAlerts(state, message) {
let timeout = 0
if (state.status.showAlert) {
state.status.showAlert = false
timeout = 300
}
setTimeout(() => {
state.status.showAlert = true
state.status.message = message
}, timeout)
},
hideAlerts(state) {
state.status.showAlert = false
},
}
The fix was a) making sure I called commit in the action parameters. and b) not using setTimeout in the mutation, but instead setting a mutation to hide, and using the actions to setTime.
I'm currently using the "request" module to get data from an external page:
if i use the following code, it doesn't work:
request(SITE_URL, function (error, response, body) {
var user = new gasStation({ id: 12345, name: 'Gustavo' });
user.save();
});
But if i make the call outside the request function it works as expected:
var user = new gasStation({ id: 12345, name: 'Gustavo' });
user.save();
request(SITE_URL, function (error, response, body) {
// some stuff
});
Why is this happening?
First never ignore your error handler's. Check if error is true. Also your URL might be malformed check that. Lastly make sure the mongoose model for user is initialized. I only saw initialization outside the request.
I have
epilogue.resource({
model: db.Question,
endpoints: ['/api/questions', '/api/questions/:id'],
associations: true
});
So when I hit /api/questions, I get back all the associations with the resources. Is there something I can pass to not get the associations in certain cases? Or should I create a new endpoint:
epilogue.resource({
model: db.Question,
endpoints: ['/api/questions2', '/api/questions2/:id']
});
One way of doing is by using milestones you can define milestone for list and read behaviour in certain case, you have access to req object so you can do changes accordingly
https://github.com/dchester/epilogue#customize-behavior
Here is an example of list call modification
// my-middleware.js
module.exports = {
list: {
write: {
before: function(req, res, context) {
// modify data before writing list data
return context.continue;
},
action: function(req, res, context) {
// change behavior of actually writing the data
return context.continue;
},
after: function(req, res, context) {
// set some sort of flag after writing list data
return context.continue;
}
}
}
};
// my-app.js
var epilogue = require('epilogue'),
restMiddleware = require('my-middleware');
epilogue.initialize({
app: app,
sequelize: sequelize
});
var userResource = epilogue.resource({
model: User,
endpoints: ['/users', '/users/:id']
});
userResource.use(restMiddleware);
In my express app, when the DELETE method below is called, the GET method is immediately called after and it's giving me an error in my angular code that says it is expected an object but got an array.
Why is my GET method being called when i'm explicitly doing res.send(204); in my DELETE method and how can I fix this?
Server console:
DELETE /notes/5357ff1d91340db03d000001 204 4ms
GET /notes 200 2ms - 2b
Express Note route
exports.get = function (db) {
return function (req, res) {
var collection = db.get('notes');
collection.find({}, {}, function (e, docs) {
res.send(docs);
});
};
};
exports.delete = function(db) {
return function(req, res) {
var note_id = req.params.id;
var collection = db.get('notes');
collection.remove(
{ _id: note_id },
function(err, doc) {
// If it failed, return error
if (err) {
res.send("There was a problem deleting that note from the database.");
} else {
console.log('were in delete success');
res.send(204);
}
}
);
}
}
app.js
var note = require('./routes/note.js');
app.get('/notes', note.get(db));
app.post('/notes', note.create(db));
app.put('/notes/:id', note.update(db));
app.delete('/notes/:id', note.delete(db));
angularjs controller
$scope.delete = function(note_id) {
var note = noteService.get();
note.$delete({id: note_id});
}
angularjs noteService
angular.module('express_example').factory('noteService',function($resource, SETTINGS) {
return $resource(SETTINGS.base + '/notes/:id', { id: '#id' },
{
//query: { method: 'GET', isArray: true },
//create: { method: 'POST', isArray: true },
update: { method: 'PUT' }
//delete: { method: 'DELETE', isArray: true }
});
});
** UPDATE **
To help paint the picture, here's the angular error i'm getting:
Error: [$resource:badcfg] Error in resource configuration. Expected response to contain an object but got an array http://errors.angularjs.org/1.2.16/$resource/badcfg?p0=object&p1=array
I'm assuming that i'm getting this error because my delete method is calling my get method (somehow) and the get method returns the entire collection.
Server side
You're removing an element from a collection in your delete function. This is done asynchronously and calling your callback when it's finished.
During this time, other requests are executed, this is why your GET request is executed before your DELETE request is finished.
The same happens in your get function, you're trying to find an element from a collection and this function is too asynchronous.
But this is server side only and it is fine, it should work this way, your problem is located client side.
Client side
If you want to delete your note after you got it, you will have to use a callback function in your angular controller which will be called only when you got your note (if you need help on that, show us your noteService angular code).
This is some basic javascript understanding problem, actions are often made asynchronously and you need callbacks to have an execution chain.
Maybe try doing something like this:
$scope.delete = function(note_id) {
var note = noteService.get({ id: note_id }, function()
{
note.$delete();
});
}
Your code doesn't make sense though, why is there a get in the $scope.delete? Why not do as simply as following:
$scope.delete = function(note_id) {
noteService.delete({ id: note_id });
}
Error
I think you get this error because of what your server sends in your exports.delete function. You're sending a string or no content at all when angular expects an object (a REST API never sends strings). You should send something like that:
res.send({
results: [],
errors: [
"Your error"
]
});
I'm not sure what is the elegant way to pass server variables in to my Model.
For example, i have an id of user that has to be implemented on my Model. But seems like Backbone with require are not able to do that.
My two options are:
Get a json file with Ajax.
Add the variable on my index.php as a global.
Someone know if exists a other way. Native on the clases?
Trying to make work the example of backbonetutorials. I am not able to throw a callback when the method fetch().
$(document).ready(function() {
var Timer = Backbone.Model.extend({
urlRoot : 'timeserver/',
defaults: {
name: '',
email: ''
}
});
var timer = new Timer({id:1});
timer.fetch({
success: function(data) {
alert('success')
},
fail: function(model, response) {
alert('fail');
},
sync: function(data) {
alert('sync')
}
});
});
The ajax request it has been threw. But does not work at all. Because any alert its dispatched.
var UserModel = Backbone.Model.extend({
urlRoot: '/user',
defaults: {
name: '',
email: ''
}
});
// Here we have set the `id` of the model
var user = new Usermodel({id: 1});
// The fetch below will perform GET /user/1
// The server should return the id, name and email from the database
user.fetch({
success: function (user) {
console.log(user);
}
})
The server will reply with a json object then you can leave the rendering part for your backbone. Based on a template for the user.
You may also want to check these out: http://backbonetutorials.com/