Search code examples
javascriptform-data

JS — how to append Array of Objects with files to FormData?


I'm developing admin dashboard with Vue, Laravel & Axios. And I have some problems with trying to upload files to api.

I replaced some real data to type of data

On Client-side I have Array of Objects:

[
    {
        id: random_generated_id,
        img: {obj},
        img_is_fullwidth: boolean,
        site_url: string,
        description: string
    },
    {
        id: random_generated_id
        img: {obj},
        img_is_fullwidth: boolean,
        site_url: string,
        description: string
    }
    ...
]

Objects can be added to Array:

addObject() {
    this.array.push({
        id: new Date().valueOf(),
        img: null,
        img_is_fullwidth: null,
        site_url: null,
        description: null
    })
}
<div v-for="(content, index) in array" :key="content.index">
    <input type="file" :ref="'content' + content.id" v-on:change="handleFileUpload(content.id)">

    <label class="checkbox">
        <input type="checkbox" v-model="content.img_is_fullwidth">
        is fullwidth?
    </label>

    <input type="text" v-model="content.site_url" required>

    <input type="text" v-model="content.description" required>
</div>

<button @click.prevent="addContent">Add content</button>

And I'm using random ids to attach image file to object by:

<input class="file-input" type="file" :ref="'content' + content.id" v-on:change="handleFileUpload(content.id)">
handleFileUpload(itemId) {
   var itemIndex = this.array.findIndex(i => i.id === itemId)
   this.array[itemIndex].img = this.$refs['content' + itemId][0].files[0]
}

So the problem is when I'm trying to post this data to api with axios, I get error:

Trying to get property 'img' of non-object

It's happened cause I'm using JSON.stringify() and image object transforms to image array:

let fd = new FormData()
fd.append('array', JSON.stringify(this.array))

Part of Laravel Controller:

$array = json_decode($request->array, true);

foreach ($array as $content) {

    $newContent = new WorkContent;

    $contentImg = $content->img;

    $contentName = uniqid();
    $contentExt = $contentImg->getClientOriginalExtension();
    $contentPath = $contentImg->storeAs('works/'.$request->client.'/'.$request->slug, $contentName.'.'.$contentExt);

    $newContent->img_url = $contentPath;

    if ($content->img_is_fullwidth == 'true') {
        $newContent->img_is_fullwidth = true;
    } else if ($content->img_is_fullwidth == 'false') {
        $newContent->img_is_fullwidth = false;
    }

    $newContent->site_url = $content->site_url;
    $newContent->description = $content->description;

    $newContent->save();

    $work->contents()->attach($newContent);
}

So, the question is: Any ideas how to solve the problem?


Solution

  • Found solution by myself:

    $contentArray = json_decode($r->contents, true);
    
    $contentImgs = $r->contentImgs;
    
            $imgIndex = 0;
    
            for ($i = 0; $i < sizeof($contentArray); $i++) {
                if($contentArray[$i]['img'] !== null) {
                    $contentArray[$i]['img'] = $r->contentImgs[$imgIndex];
                }
            }
    
            foreach ($contentArray as $content) {
                $newContent = new WorkContent;
    
                $contentImg = $content['img'];
    
                if ($contentImg !== null) {
                    $contentName = uniqid();
                    $contentExt = $contentImg->getClientOriginalExtension();
                    $contentPath = $contentImg->storeAs('works/'.$r->client.'/'.$r->slug, $contentName.'.'.$contentExt);
    
                    $newContent->img_url = $contentPath;
                }
    
                if ($content['img_is_fullwidth'] == 'true') {
                    $newContent->img_is_fullwidth = true;
                } else if ($content['img_is_fullwidth'] == 'false') {
                    $newContent->img_is_fullwidth = false;
                }
    
                $newContent->site_url = $content['site_url'];
                $newContent->description = $content['description'];
    
                $newContent->work_id = $w->id;
    
                $newContent->save();
            }