Skip to content
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

[RFR] Document the way to define nested entity urls for relationships #711

Merged
merged 1 commit into from
Sep 30, 2015

Conversation

fzaninotto
Copy link
Member

By default, ng-admin uses filters to fetch entities related to another one. For instance, to fetch all the comments related to the post entity #123, ng-admin calls the following url:

http://[baseApiUrl]/comments?filters={"post_id":123}

Some API servers only support a special type of URL for that case:

http://[baseApiUrl]/posts/123/comments

Restangular doesn't allow to modify the URL of an outgoing request (see Restangular issue #603), so in order to achieve that you must use an interceptor on the $http Angular service.

myApp.config(['$httpProvider', function($httpProvider) {
    $httpProvider.interceptors.push(function() {
        return {
            request: function(config) {
                // test for /comments?filters={post_id:XXX}
                if (/\/comments$/.test(config.url) && config.params.filter && config.params.filter.post_id) {
                    config.url = config.url.replace('comments', 'posts/' + config.params.filter.post_id + '/comments');
                    delete config.params.filter.post_id;
                }
                return config;
            },
        };
    });
}]);

fzaninotto added a commit that referenced this pull request Sep 30, 2015
[RFR] Document the way to define nested entity urls for relationships
@fzaninotto fzaninotto merged commit 75b1684 into master Sep 30, 2015
@fzaninotto fzaninotto deleted the nested_url branch September 30, 2015 08:18
@vellotis
Copy link

I have come up with another solution.

myApp.config(['$httpProvider', function($httpProvider) {
    $httpProvider.interceptors.push(function() {
        return {
            request: function(config) {
                // Check if any filter is present
                try {
                    config.params._filter['try'];
                } catch (err) {
                    return config;
                }

                // Get only pathname not full url
                var a = document.createElement('a');
                a.href = config.url;

                // Find keys starting with ":"
                var matches = a.pathname.match(/(\:[^\/]*)/g);

                if (matches) {
                    // Remove ":" from keys
                    matches = matches.map(function(match) {
                        return match.replace(':', '');
                    });

                    // Find if all keys present in filters
                    if (matches.every(function(match) { return !!config.params._filter[match]; })) {
                        // Perform url manipulation
                        matches.forEach(function(match) {
                            // Replace key with value
                            a.pathname = a.pathname.replace(":" + match, config.params._filters[match]);
                            // Delete filter
                            delete config.params._filters[match];
                        });

                        // Update url
                        config.url = a.href;
                    }
                }

                return config;
            }
        };
    });
}]);
myApp.config(['NgAdminConfigurationProvider', function(nga) {
    admin = nga.application('My ngAdmin App');

    client = nga.entity('clients').identifier(nga.field('personal_id'));

    // set the fields of the user entity list view
    client.listView()
    .fields([
        nga.field('personal_id').label('Personal ID'),
        nga.field('first_name').label('First name'),
        nga.field('last_name').label('Last name')
    ])
    .batchActions([])
    .listActions(['show'])

    client.showView()
    .title 'Client detailed info for #{{ entry.values.personal_id }}'
    .fields([
        nga.field('personal_id').label('Personal ID'),
        nga.field('first_name').label('First name'),
        nga.field('last_name').label('Last name'),
        nga.field('companies', 'referenced_list')
            .targetEntity(
                nga.entity('companies')
                    .identifier(nga.field('reg_no')) // Unique field returned by API
                    .url("/clients/:personal_id/companies"); // Resource URL including parent resource id
                )
            .targetReferenceField('personal_id') // Field to be replaced in URL
            .targetFields([
                nga.field('reg_no').label('Reg. number'),
                nga.field('name').label('Name'),
                nga.field('created_at', 'datetime').label('Created at')
               ])
          ])
}]);

@bicoi
Copy link

bicoi commented Oct 22, 2015

How can I show nested object?
Example I want to show detail comment of a post has following API format:
http://[baseApiUrl]/posts/123/comments/234

Currently I can't pass post's ID to url of comment detail.

Please help!!!

@bicoi
Copy link

bicoi commented Oct 23, 2015

I have found a solution by reference to issue 627

@rxcai
Copy link

rxcai commented Apr 25, 2016

Attention that, maybe it's because change of codes, configuration parameters have changed:

config.params._filters

@fzaninotto Maybe should update in the wiki as well.

myApp.config(['$httpProvider', function($httpProvider) {
    $httpProvider.interceptors.push(function() {
        return {
            request: function(config) {
                // test for /comments?filters={post_id:XXX}
                if (/\/comments$/.test(config.url) && config.params._filters && config.params._filters.post_id) {
                    config.url = config.url.replace('comments', 'posts/' + config.params._filters.post_id + '/comments');
                    delete config.params._filters.post_id;
                }
                return config;
            },
        };
    });
}]);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants