New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to fetch associations #382
Comments
Yes. Have a look at the example how to fetch related items. Basically, in your hook you can access another service via module.exports = function(options) {
return function(hook) {
return hook.app.service('otherservice').find({
query: { name: 'David' }
}).then(page => {
const davids = page.data;
hook.data.davids = davids;
// Or you can replace all the data with
hook.data = { davids };
// IMPORTANT: always return the `hook` object in the end
return hook;
});
};
}; |
@daffl Thank you very much. I figured it would be this easy, but couldn't find it in the documentation, I must have missed it. |
Ok so this is a find call that I have this before hook (just if you need that info) I am only getting 25 but there are hundreds. If I remove the limit, I only get 5 items. What is going on and how do I get all?
|
It depends on what option you set for return hook.app.service('data').find({
paginate: false,
query: { dataSet: dataSet }
}).then(data => {
// data is an array
}); |
When I do that I get 0 records. When I remove the pagination: false I get 25. |
Does |
|
I just verified that const feathers = require('feathers');
const rest = require('feathers-rest');
const socketio = require('feathers-socketio');
const hooks = require('feathers-hooks');
const nedb = require('feathers-nedb');
const bodyParser = require('body-parser');
const handler = require('feathers-errors/handler');
const NeDB = require('nedb');
// A Feathers app is the same as an Express app
const app = feathers();
const db = new NeDB({
filename: './data/messages.db',
autoload: true
});
// Parse HTTP JSON bodies
app.use(bodyParser.json());
// Parse URL-encoded params
app.use(bodyParser.urlencoded({ extended: true }));
// Register hooks module
app.configure(hooks());
// Add REST API support
app.configure(rest());
// Configure Socket.io real-time APIs
app.configure(socketio());
// Register our memory "users" service
app.use('/todos', nedb({
Model: db,
paginate: {
default: 20,
max: 50
}
}));
// Register a nicer error handler than the default Express one
app.use(handler());
const promises = [];
for(let i = 0; i < 700; i++) {
promises.push(app.service('todos').create({ text: `Item #${i}`}));
}
Promise.all(promises).then(function() {
app.service('todos').find({
paginate: false,
query: {}
}).then(data => console.log(data));
});
// Start the server
app.listen(3333); I am getting 700 items logged to the console. Did you accidentally add |
This is what I did:
Still get 0 results and 25 with pagination variable not there and 5 results without limit. However, I got it working with this:
As you see the results are no longer in the page.data but is just in the page variable. Lesson learned :) |
Oh and thanks @daffl for your help. |
On the client side it doesn't work. (the |
Only app.service('data').before({
find(hook) {
if(hook.params.query && hook.params.query.$paginate) {
hook.params.paginate = hook.params.query.$paginate === 'false' || hook.params.query.$paginate === false;
delete hook.params.query.$paginate;
}
}
}); |
I understand the warning of not allowing pagination on the client side, however, the tool I am making is just for me to run locally. Thanks again for everything. |
@daffl Hi, I'm using the code you have posted to retrieve posts a user has. module.exports = function(options) {
return function(hook) {
// hook.getPosts = true;
const id = hook.result.id;
console.log("id");
return hook.app.service('posts').find({
paginate: false,
query: { postedBy: id }
}).then(function(posts){
console.log("posts");
// Set the posts on the user property
hook.result.posts = posts.data;
// Always return the hook object or `undefined`
return hook;
});
};
}; But this causes the server to go in an infinite loop and the node app ultimately crashes. I am using MySQL as my DB connected by sequelize. What am I doing wrong? UpdateI had setup a similar hook for posts to populate the user field based on the Any ideas how to populate only a shallow related item, i.e, the hook would pull only the related items on only the first level. |
@daffl Your idea is awesome, though the code didn't work.
One more thing to consider is, when pagination disabled, the data is not in res.data but res itself. |
@fortunes-technology You are right. I updated my code snippet. This should work: app.service('data').before({
find(hook) {
if(hook.params.query && hook.params.query.$paginate) {
hook.params.paginate = hook.params.query.$paginate === 'false' || hook.params.query.$paginate === false;
delete hook.params.query.$paginate;
}
}
}); |
I think if $paginate is set to false (which is the point of this hook, to disable it... ), the if is going to be false, too. Maybe app.service('data').before({
find(hook) {
if(hook.params.query && hook.params.query.hasOwnProperty('$paginate')) {
hook.params.paginate = hook.params.query.$paginate === 'false' || hook.params.query.$paginate === false;
delete hook.params.query.$paginate;
}
}
}); |
Hi there. Could someone tell me if feathers services have findOne functionality or how to implement it? Thanks! |
A app.service('myservice').find({ query: { name: 'test', $limit: 1 } })
.then(page => page.data[0])
.then(result => console.log('Got', result); |
@daffl I asked because mongoose has findOne and I suggested that it doesn't search over all rest collection if something already found. So, I thought about findOne as something smarter then search with limit=1... That's why I asked. |
A common scenario is we need to access another service from inside the hook, I propose to revive a legacy documentation found on this issue feathersjs/feathers#382
I usually do this for a quick findOne:
|
I just made a plugin for a |
I couldn't find any example on how to add the $paginate workaround for the client. So I created a before hook that runs from the app.hooks.js file with some modifications:
|
Currently it issues the following warning: (node:6686) DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.
How would you go about writing a unit or integration test for this? |
The same as writing any other test for Feathers. |
so if i have the following in my hook
how do i "mock" the context.app.service in my unit test? do i need to add it to my contextBefore object?
i'm using the unit-test auto generated from the feathers-plus generator. or should i be using an integration test instead? |
I have gone the mocking route some time ago. I think its a very bad idea. You will eventually have to mock more and more of Feathers. There is no guarentee your mocks function as feathers do and you can get false negatives, as I did. Instanciating a Feathers app is very fast, so use Feathers instead of mocks. That's how the appraoch the cli+ test take. I wrote an article that refers to this. https://medium.com/feathers-plus/automatic-tests-with-feathers-plus-cli-4844721a29cf |
thanks eddyy, i've seen that, great article, really helped. i was struggling on how to add the app to my context object but working it out eventually, i think!
Then i had to amend the test so it used async.
Is that the right way to do it or is there a better way? |
Looks good |
can use query $limit : null to bypass too |
What strikes me, is that this line: |
So I have developed an app with the feathers framework. I have a hook attached to a database service that I want to access data from another service. Is this possible, and easy? I want that service to be able to access several neDB files. How do I do this?
The text was updated successfully, but these errors were encountered: