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

Nested Services or Nested Configuration #1471

Open
mtraynham opened this issue Apr 24, 2017 · 0 comments
Open

Nested Services or Nested Configuration #1471

mtraynham opened this issue Apr 24, 2017 · 0 comments

Comments

@mtraynham
Copy link

mtraynham commented Apr 24, 2017

I've seen multiple posts about this (#139, #413, #585, #1254, #1381), but none of those provide a concrete solution. I think it really stems from the fact that some ReST API's just don't abide by the same rules throughout the path hierarchy. id fields are different, responses/post body may be wildly different.

Let's take for instance an example resource:
/api/cars/{modelId}/wheels/{wheelId}

So far we have two different ID fields. From the documentation, it seems like this is should be the approach:

Restangular.withConfig(RestangularConfigurer =>
    RestangularConfigurer
        .setRestangularFields({id: 'modelId', route: 'cars'})
        .setRestangularFields({id: 'wheelId', route: 'wheels', parentResource: 'cars'})

But this does not work. Per the FAQ documentation, we need to set the getIdFromElem method.

If the ReST API also expects different information for the post body and returns different things for get/getList, the implementation starts to get unwieldy as shove everything under the top parent resource, like so:

.addResponseInterceptor((data, operation, what, url) => {
    if (what === 'cars') {
        if (operation === 'getList') {
            return data.map(name => ({name}));
        }
        if (operation === 'get') {
            const urlSplit = url.split('/');
            const name = urlSplit[urlSplit.length - 1];
            return {name, descriptor: data};
        }
    }
    if (what === 'wheels') {
        if (operation === 'getList') {
            return data.map(name => ({name}));
        }
        if (operation === 'get') {
            const urlSplit = url.split('/');
            const name = urlSplit[urlSplit.length - 1];
            return {name, descriptor: data};
        }
    }
    return data;
})

Realistically, it would make the most sense if you could create a Restangular configuration and use that to create a service under a parent.

const carWheelConfig = Restangular.withConfig(RestangularConfigurer =>
    RestangularConfigurer
        .setRestangularFields({id: 'wheelId', route: 'wheels'})
        .addResponseInterceptor((data, operation, url) => {
            if (operation === 'getList') {
                return data.map(name => ({name}));
            }
            if (operation === 'get') {
                const urlSplit = url.split('/');
                const name = urlSplit[urlSplit.length - 1];
                return {name, descriptor: data};
            }
            return data;
        });

const carConfig = Restangular.withConfig(RestangularConfigurer =>
    RestangularConfigurer
        .setRestangularFields({id: 'modelId', route: 'cars'})
        .addResponseInterceptor((data, operation, url) => {
            if (operation === 'getList') {
                return data.map(name => ({name}));
            }
            if (operation === 'get') {
                const urlSplit = url.split('/');
                const name = urlSplit[urlSplit.length - 1];
                return {name, descriptor: data};
            }
            return data;
        })
        .addElementTransformer(element, false, element => 
            Object.assign(element, {
                wheels: carWheelConfig.service(element)
            }));

The addElementTransformer for adding a wheel service to car, seems like it should work, but invoking Restangular.service(parent) removes all the prior configuration of wheelConfig.


Is there anyway to create a nested configuration/service that does not directly inherit (in this broken use case override) any configuration from the parent resource, except maybe the path building aspect?

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

No branches or pull requests

1 participant