kimkha / aor-loopback

Loopback-style REST Client for Admin-on-rest
MIT License
44 stars 23 forks source link

Uploading Images With aor-loopback #4

Open kodepareek opened 7 years ago

kodepareek commented 7 years ago

Hello

Am using aor-loopback to connect with my API.

ON trying to create image upload capability I used the following aor guide to create a wrapper on aor-loopback

https://marmelab.com/admin-on-rest/RestClients.html#decorating-your-rest-client-example-of-file-upload

Here is my wrapper code.

const fileUploadRESTWrapper = requestHandler => (type, resource, params) => {
    if (type === 'UPDATE' && resource === 'tales') {
      if (params.data.faceBookImage && params.data.faceBookImage.length) {
        let form = new FormData()
        form.append('file', params.data.faceBookImage[0]);
        delete params.data.faceBookImage
        form.append('model', JSON.stringify(params.data))
        return requestHandler(type, resource, {
            ...params,
            data: form
          },
        )
      }
    }
    return requestHandler(type, resource, params);
};

export default fileUploadRESTWrapper;

I encountered some issues. After looking through the aor-loopback source code I found that

            case _types.UPDATE:
                url = apiUrl + '/' + resource + '/' + params.id;
                options.method = 'PUT';
                options.body = JSON.stringify(params.data);
                break;

aor-loopback is JSON.stringifying the entire response body. Stringifying is removing the image from the FormData object.

Suggestions: It would be great if you could also export the fetchJson method from the package. Someone like me could then create a case in the wrapper above.

                url = apiUrl + '/' + resource + '/' + params.id;
                options.method = 'PUT';
                options.body = params.data
                fetchJson(url, options)

This should solve a number of other use cases including create etc.

Above is just a suggestion and you may choose any other idea to account for the image upload use case as well.

Thanks and regards

kodepareek commented 7 years ago

Well I managed to get this done. Do you want me to share documentation?

kimkha commented 7 years ago

Sure, please..

kodepareek commented 7 years ago

I finally had to completely bypass AOR loopback and use AOR fetchUtils to make the req and response.

import { fetchUtils } from 'admin-on-rest';
// if condition below will have code for the specific case the user is trying to intercept. 
  if (type === 'UPDATE' && ['tales', 'trackTale'].indexOf(resource) !== -1) {
    let form = new FormData()
    if (params.data.image && params.data.image.length) {
      form.append('image', params.data.image[0]);
    }
    form.append('model', JSON.stringify(params.data))
//base is the base URL for the server    
let url = base + '/' + resource + '/' + params.id; 
    options.method = 'PUT';
    options.body = form
    return fetchUtils.fetchJson(url, options)
      .then((response) => {
        const {json} = response;
        //admin on rest needs the {data} key
        return { data: json };
    })

Quite simple in the end. I think this can be extended to all cases. Just check if there is form data in the request being made. We can definitely handle form requests for single image for the UPDATE type