Search code examples
javascriptvue.jsecmascript-6ecmascript-2016

Import/Require JSON file as clone into Vue data property


I am having an issue with using external data within a Vue data property.

Consider the following snippet from my component:

export default {

    data() {
        return {
            gallery: require('core-js/support/some-page-gallery.json')
        }
    },

    created() {

        // Prepare the images for the gallery
        this._buildImageURLs();

    },

    methods: {

        /**
         * Build the image urls for the gallery.
         *
         * @return void
         */
        _buildImageURLs() {

            this.gallery.forEach(image => {
                Object.entries(image.images).forEach(([key, source]) => {
                    image.images[key] = this.$staticAsset(`/assets/images/misc/${source}`);
                });
            });

        }

    }

}

The issue with the above is that modifying this.gallery seems to modify the originally imported array.

This results in the following:

  • On page load, image.images[0] is equal to example.com/assets/images/misc/example.jpg
  • When navigating away, and then back to that page, image.images[0] is equal to example.com/assets/images/misc/example.com/assets/images/misc/example.jpg

What is the best way to require my JSON file as a clone instead of as a reference? Assuming that is what is going wrong here...

Alternatively, is there a better way to import the data into my component?

What have I tried?

I have also tried using import but this results in exactly the same result.

In addition, I have thought about passing this.gallery as a parameter to this._buildImageURLs() and I am fairly confident I could get this to work but I am hesitant as it doesn't seem like the correct way to do this.

Update

Just in case the above is not clear; the issue I am facing is that this.gallery is acting as a reference to the imported file. As a result, the imported data is maintaining it's edited state throughout my application.

When I first last on the page, the _buildImageURLs method amends the data correctly. But if I navigate away, and then back to the page, the modified data is modified again which results in duplicate modifications.


Solution

  • You need to copy the JSON before do any mutation on the forEach statement:

    const GALLERY = require('core-js/support/some-page-gallery.json');
    
    export default {
    
        data(){
            retrun {
                gallery: JSON.parse(JSON.stringify(GALLERY)); 
            }
        }
    
        //rest of your code...
    }
    

    Check this question: How to create and clone a JSON object?