Giter Club home page Giter Club logo

Comments (30)

jmdobry avatar jmdobry commented on July 30, 2024 1

Now:

Nested Resource Endpoints

Add parent: true to a belongsTo relationship to activate nested resource endpoints for the resource. Angular-data will attempt to find the appropriate key in order to build the url. If the parent key cannot be found then angular-data will resort to a non-nested url unless you manually provide the id of the parent.

Example:

DS.defineResource({
  name: 'comment',
  relations: {
    belongsTo: {
      post: {
        parent: true,
        localKey: 'postId',
        localField: 'post'
      }
    }
  }
});

// The comment isn't in the data store yet, so angular-data wouldn't know 
// what the id of the parent "post" would be, so we pass it in manually
DS.find('comment', 5, { params: { postId: 4 } }); // GET /post/4/comment/5

// vs 

DS.find('comment', 5); // GET /comment/5

DS.inject('comment', { id: 1, postId: 2 });

// We don't have to provide the parentKey here
// because angular-data found it in the comment
DS.update('comment', 1, { content: 'stuff' }); // PUT /post/2/comment/1

// If you don't want the nested for just one of the calls then
// you can do the following:
DS.update('comment', 1, { content: 'stuff' }, { params: { postId: false } }); // PUT /comment/1

from js-data-angular.

mattatcha avatar mattatcha commented on July 30, 2024

How do you think something like this would work?

DS.defineResource({
    name: 'post'
});
DS.defineResource({
    parent: 'post',
    name: 'comment'
});

// GET http://localhost/post/10/comment
DS.findAll('comment', {postId: 10})
    .then(function(comments){
        // Do something here
    });

// GET http://localhost/post/10/comment/1
DS.find('comment', {postId: 10, commentId: 1})
    .then(function(comment){
        // Do something here
    });

from js-data-angular.

jmdobry avatar jmdobry commented on July 30, 2024

@MattAitchison I see what you're getting at. However, your example seems to preclude the idea that GET http://localhost/comment/1 could be valid in addition to GET http://localhost/post/10/comment/1. I think angular-data would need to be capable to doing both. To extend your example:

DS.defineResource({
    name: 'post'
});
DS.defineResource({
    parent: 'post',
    name: 'comment'
});

// GET http://localhost/post/10/comment
DS.findAll('comment', { postId: 10 });

// GET http://localhost/comment
DS.findAll('comment');

// GET http://localhost/post/10/comment/1
DS.find('comment', 1, { postId: 10 });

// GET http://localhost/comment/1
DS.find('comment', 1);

In addition to nested resources, I'd like also to in general support belongsTo, hasOne, and hasMany relationships. The two seem related, so the implementation of one would affect the implementation of the other.

Once I've wrapped up relations in Reheat, I will move on to this.

from js-data-angular.

mattatcha avatar mattatcha commented on July 30, 2024

I just thought of it real quick. I didn't think about that part.

I do like your example too. That was one of the other ways I was thinking about it.

I have no clue how you wanted to implement relations but I have thought about it a little. Maybe they could work like they do in reheat. So you could do something like DS.find('post', 1, {with: 'comments'});. This could then form a url like http://localhost/post/1?with=comments. The main problem I see with this is that it would require support on the server side. So maybe angular-data could make two requests to the server. One to http://localhost/post/1 which should give all the comment IDs and then another to get all the comments.

Maybe I am just making the relations more complicated than they need to be though. I haven't used any libraries for them before.

from js-data-angular.

AlJohri avatar AlJohri commented on July 30, 2024

@MattAitchison, @jmdobry Can you check out the way relations are done in ngActiveResource

https://github.com/FacultyCreative/ngActiveResource
and check out this issue about how their implementation is not ENTIRELY working out for me
FacultyCreative/ngActiveResource#40

from js-data-angular.

Patrik-Lundqvist avatar Patrik-Lundqvist commented on July 30, 2024

Any news on this now that relations has been worked on?

from js-data-angular.

kentcdodds avatar kentcdodds commented on July 30, 2024

Would probably be something good to include in the wiki. I haven't done anything like this so I wont be able to help here, but thought I'd give this suggestion :-)

from js-data-angular.

jmdobry avatar jmdobry commented on July 30, 2024

@kentcdodds I seem to be missing something. Put what on the wiki? What suggestion?

from js-data-angular.

jmdobry avatar jmdobry commented on July 30, 2024

@kentcdodds I looked at the wiki and realized that the workaround you suggested a while back is irrelevant now that support for relations has been added.

from js-data-angular.

kentcdodds avatar kentcdodds commented on July 30, 2024

Perhaps it's been documented elsewhere now, but I just that that since @Patrik-Lundqvist was asking it may not be easy to find. Feel free to remove my out of date wiki entry :-)

from js-data-angular.

jmdobry avatar jmdobry commented on July 30, 2024

Relations are implemented and documented, but this nested resources issue is about something slightly different. It's about being able to handle nested resource endpoints, like /posts/43/comment/2, which I have not tackled yet.

from js-data-angular.

jmdobry avatar jmdobry commented on July 30, 2024

@Patrik-Lundqvist A solution is in the works

from js-data-angular.

jmdobry avatar jmdobry commented on July 30, 2024

My current implementation is this:

Nested Resource Endpoints

Add parent: true to a belongsTo relationship to activate nested resource endpoints for the resource. Angular-data will attempt to find the appropriate key in order to build the url. If the parent key cannot be found then angular-data will resort to a non-nested url unless you manually provide the id of the parent.

Example:

DS.defineResource({
  name: 'comment',
  relations: {
    belongsTo: {
      post: {
        parent: true,
        localKey: 'postId',
        localField: 'post'
      }
    }
  }
});

// The comment isn't in the data store yet, so angular-data wouldn't know 
// what the id of the parent "post" would be, so we pass it in manually
DS.find('comment', 5, { parentKey: 4 }); // GET /post/4/comment/5

// vs 

DS.find('comment', 5); // GET /comment/5

DS.inject('comment', { id: 1, postId: 2 });

// We don't have to provide the parentKey here
// because angular-data found it in the comment
DS.update('comment', 1, { content: 'stuff' }); // PUT /post/2/comment/1

// If you don't want the nested for just one of the calls then
// you can do the following:
DS.update('comment', 1, { content: 'stuff' }, { nested: false ); // PUT /comment/1

from js-data-angular.

Patrik-Lundqvist avatar Patrik-Lundqvist commented on July 30, 2024

Looks great! I'll try it out

from js-data-angular.

jmdobry avatar jmdobry commented on July 30, 2024

I think it should work with findAll, updateAll, and destroyAll, but I haven't tested it yet.

from js-data-angular.

Patrik-Lundqvist avatar Patrik-Lundqvist commented on July 30, 2024

Just tested DS.update with nested set to false but it didn't work.
I noticed the options parameter wasn't set for the update function here

Should be:

resourceConfig.getEndpoint(id, options)

from js-data-angular.

jmdobry avatar jmdobry commented on July 30, 2024

@Patrik-Lundqvist Good catch. This is all on master now. I'll have to flesh out the tests a little more.

from js-data-angular.

Patrik-Lundqvist avatar Patrik-Lundqvist commented on July 30, 2024

I ran into some problem with the current implementation where I have minimized my path nesting. Lets take this example: /orgs/{org_id}/customers/{customer_id}/projects/{project_id}

In order to not have complicated paths when retrieving projects and its child resources I have minimized my paths as described here. For instance, /customers/1/projects gets all projects which belongs to customer 1. Right now its only possible to get the full resource path or do requests to /projects.

from js-data-angular.

jmdobry avatar jmdobry commented on July 30, 2024

Okay, so in addition to

  • /orgs/{org_id}
  • /orgs/{org_id}/customers/{customer_id}
  • /orgs/{org_id}/customers/{customer_id}/projects/{project_id}

You also want to be able able to do just /customers/{customer_id}/projects/{project_id} correct?

from js-data-angular.

Patrik-Lundqvist avatar Patrik-Lundqvist commented on July 30, 2024

Exactly, and also get/post projects with /customers/{customer_id}/projects

from js-data-angular.

jmdobry avatar jmdobry commented on July 30, 2024

Yeah, the current implementation isn't that flexible. I'll have to rework
it.
On Aug 21, 2014 8:31 AM, "Patrik Lundqvist" [email protected]
wrote:

Exactly, and also get/post projects with /customers/{customer_id}/projects


Reply to this email directly or view it on GitHub
#40 (comment).

from js-data-angular.

Patrik-Lundqvist avatar Patrik-Lundqvist commented on July 30, 2024

Alright! By the way, maybe nested resources could be used when loading relations also. So that DS.loadRelations('customer', customer, ['project']) would send a request to:
/customers/{customer_id}/projects instead of /projects?customerId={customer_id}

from js-data-angular.

jmdobry avatar jmdobry commented on July 30, 2024

The new implementation should take care of that.

from js-data-angular.

jmdobry avatar jmdobry commented on July 30, 2024

@Patrik-Lundqvist So in your case you would now do something like:

DS.update('project', 5, { some: 'stuff' }, { params: { org_id: false } });
// If project "5" isn't already in the data store
DS.update('project', 5, { some: 'stuff' }, { params: { org_id: false, customer_id: 6 } });

And you should get PUT /customers/6/projects/5 with {"some":"stuff"} as the payload.

from js-data-angular.

Patrik-Lundqvist avatar Patrik-Lundqvist commented on July 30, 2024

Works great, very nice! But how will the parent property handle multiple parents? Lets say that a user both belongs to an organization and a team which should make both of these paths valid:

  • /orgs/{org_id}/users
  • /teams/{team_id}/users

The second path would be called when loading relations for a team.

from js-data-angular.

jmdobry avatar jmdobry commented on July 30, 2024

I feel like I'm going down the rabbit hole...Let me think about this one.

from js-data-angular.

jmdobry avatar jmdobry commented on July 30, 2024

@Patrik-Lundqvist I'm going to consider this issue complete enough for the beta. Any other potential enhancements should go into their own issue.

from js-data-angular.

demisx avatar demisx commented on July 30, 2024

This doesn't appear to work with findAll

DS.defineResource({
      name: 'category',
      endpoint: '/categories',
      relations: {
        belongsTo: {
          section: {
            parent: true,
            localKey: 'secId',
            localField: 'section'
          }
        }
      }

Then calling:

Category.findAll({ params: { secId: 1 } }) 

Produces this URL:

 http://dev.api.dimaslist.org:3000/v1/categories?params=%7B%22secId%22:1%7D

Expected URL:

 http://dev.api.dimaslist.org:3000/v1/sections/1/categories

from js-data-angular.

jmdobry avatar jmdobry commented on July 30, 2024

@demisx You need to do Category.findAll({ secId: 1 }) or Category(null, { params: { secId: 1 } })

from js-data-angular.

demisx avatar demisx commented on July 30, 2024

👍 That worked!

from js-data-angular.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.