Skip to content

Latest commit

 

History

History
157 lines (146 loc) · 4.48 KB

nova-resource-request-mixin.md

File metadata and controls

157 lines (146 loc) · 4.48 KB

Laravel Nova Resource Request Helper Vue Mixin

A Vue Mixin for mapping Nova Resource Responses to normal objects / arrays.

Some Nova Routes return resource responses (index, show), others like create do not. The included uploadResource method doesn't need to be mapped for example.

Nova Resource Response Structure:

[
    {
       "resource":{
          "fields":[
             {"attribute":"id", "value":1},
             {"attribute":"size", "value":4312},
             {
                "attribute":"file",
                "value":"screen-shot1.png",
                "thumbnailUrl":"http:\/\/laravel7-test.test\/storage\/media\/screen-shot1.png",
                "previewUrl":"http:\/\/laravel7-test.test\/storage\/media\/screen-shot1.png"
             }
          ]
       }
    },
    {
       "resource":{
          "fields":[
             {"attribute":"id", "value":2},
             {"attribute":"size", "value":4312},
             {
                "attribute":"file",
                "value":"screen-shot2.png",
                "thumbnailUrl":"http:\/\/laravel7-test.test\/storage\/media\/screen-shot2.png",
                "previewUrl":"http:\/\/laravel7-test.test\/storage\/media\/screen-shot2.png"
             }
          ]
       }
    }
]

Mapped to Normal Object

{
"id": 1,
"size": 4312,
"file": "screen-shot.png",
"thumbnailUrl":"http:\/\/laravel7-test.test\/storage\/media\/screen-shot.png",
"previewUrl":"http:\/\/laravel7-test.test\/storage\/media\/screen-shot.png",
}

Usage

this.fetchResourceEntity('media',id).then((entity)=>{
    this.entity = entity
})
this.fetchResourceCollection('media', {
    orderByDirection: this.sort,
    search: this.searchTerm,
    orderBy: this.orderBy,
    page: this.page,
    perPage: 50,
})
.then((entities) => {
    this.entities = entities
})
this.uploadResource('media', {file}).then((entity) => {
    this.$toasted.show(this.__('Uploaded: :name',entity), {
        type: 'success'
    })
})
export default {
    methods:{
        /**
         * Map Nova Resource to Normal Object Format Including Additional Properties.
         * @param resource {Object}
         * @return {Object}
         */
        resourceToObject({fields}) {
            return fields.reduce((obj, item) => {
                obj[item.attribute] = item.value
                if(item.hasOwnProperty('thumbnailUrl')){
                    obj.url = item.thumbnailUrl
                }else if(item.hasOwnProperty('previewUrl')){
                    obj.url = item.previewUrl
                }
                if(item.hasOwnProperty('meta')){
                    obj.meta = item.meta
                }
                return obj
            }, {})
        },
        /**
         * Fetch Resource Entity
         * @param resourceKey {String}
         * @param id {String|Number}
         * @return {Promise<Array>}
         */
        async fetchResourceEntity(resourceKey, id){
            return await Nova.request()
                .get(`/nova-api/${resourceKey}/${id}`)
                .then(({data})=>this.resourceToObject(data.resource))
                .catch(this.handleResourceError)
        },
        /**
         * Fetch Resource Collection
         * @param resourceKey {String}
         * @param params {Object}
         * @return {Promise<Array>}
         */
        async fetchResourceCollection(resourceKey, params){
            return await Nova.request()
                .get(`/nova-api/${resourceKey}`,{params})
                .then(({data})=>data.resources.map((resource)=>this.resourceToObject(resource)))
                .catch(this.handleResourceError)
        },
        /**
         * Fetch Resource Entity as Object
         * @param resourceKey {String}
         * @param params {Object}
         * @return {Promise<Array>}
         */
        async uploadResource(resourceKey, params){
            const data = new FormData
            Object.entries(params).forEach(([key,value])=>data.append(key, value))
            return await Nova.request()
                .post(`/nova-api/${resourceKey}`,data)
                .then(({data})=>data.resource)
                .catch(this.handleResourceError)
        },
        /**
         * Handle Resource Error
         * @param error {Error}
         * @return void
         */
        handleResourceError(error){
            this.$toasted.show(this.__(':message',{message:error.toString()}),{
                type: 'error'
            })
        }
    }
}