Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # 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;
            },
        };
    });
}]);

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

Successfully merging this pull request may close these issues.

4 participants