samedi 28 décembre 2019

Update image in vue and laravel works with some errors

I have a form to store and update data including an image, however when I try to Store Or update Image with another Image that breaks my validation rule the validation works fine but if I try to re-update any record without including image I get the same validation message like if I'm updating with invalid image it doesn't work fine back till I store or update including upload a valid Image then every thing works fine in store or update even if updating without image. Note:The store and update work fine if all data are valid in the first time.

This is my form

<template>
<form class="border border-info rounded" style="padding: 0px 15px 15px 15px;">
    <button @click="resetForm" type="button" data-toggle="tooltip" title="Reset Form" class="close" aria-label="Close">
        <span aria-hidden="true">&times;</span>
    </button>
    <div style="width: 100%;">
        <div style="float:left; width: 40%">
            <div class="form-group" style="padding-top: 25px; margin-top: 20px; width: 343px;">
                <input v-model="channel.name"
                       name="name"
                       type="text"
                       maxlength="100"
                       class="form-control"
                       placeholder="Channel title"
                       required="required" />
            </div>
            <div class="form-group">
                <div class="row" style="margin: 40px 0 35px 0">
                    <label style="padding-top: 5px">Base color</label>
                    <input v-model="channel.baseColor"
                           name="base_color"
                           type="color"
                           class="form-control color-picker"
                           style="margin-left: 229px;"
                           data-toggle="tooltip" title="Pick Color"/>
                </div>
            </div>
            <div class="form-group">
                <div class="row" style="margin: 40px 0 35px 0">
                    <label style="padding-top: 5px">Complementary color</label>
                    <input v-model="channel.complementaryColor"
                           name="complementary_color"
                           type="color"
                           class="form-control color-picker"
                           style="margin-left: 150px;"
                           data-toggle="tooltip" title="Pick Color"/>
                </div>
            </div>
        </div>
        <div class="form-group" style="float:right; width: 40%">
            <image-upload :avatar="channel.avatarUrl"></image-upload>
        </div>
    </div>

    <button
        @click.prevent="editing ? updateChannel() : addChannel()"
        type="submit" class="btn btn-outline-primary btn-block"
        v-text="editing ? 'Update Channel' : 'Add Channel'">
    </button>
</form>
</template>

<script>
import ImageUpload from '../../ImageUpload';

class Channel {
    constructor(channel){
        this.name = channel.name || "";
        this.avatarUrl = channel.avatar_path || "";
        this.baseColor = channel.bg_base_color || "";
        this.complementaryColor  = channel.bg_complementary_color || "";
    };
}

const data = new FormData();

export default {
    name: "AddEditChannel",
    components: {ImageUpload},
    data() {
        return {
            channel: new Channel({}),
            editing: false,
            channelId:'',
            file: null
        }
    },
    created() {
        this.$parent.$on('edit_channel', ({channel}) => {
            this.resetForm();
            this.editing = true;
            this.channelId = channel.id;
            this.channel = new Channel(channel);
        });
        //
        this.$on('avatar_loaded', (avatar) => {
            this.channel.avatarUrl = avatar.src;
            this.file = avatar.file;
        });
    },
    methods: {
        resetForm() {
            this.channel = new Channel({});
            this.channelId = '';
            this.file = null;
            this.editing = false;
        },
        addChannel() {
                data.append('name', this.channel.name);
                data.append('base_color', this.channel.baseColor);
                data.append('complementary_color', this.channel.complementaryColor);
                data.append('avatar', this.file);

                data.append('_method', 'POST');

                axios.post('/dashboard/channels', data).then(resp => {
                    this.$parent.$emit('channel_created', resp.data)
                }).catch(error => {
                    flash(error.response.data, 'danger', 'backEndStyle');
                });

                this.resetForm();

        },
        updateChannel() {
                data.append('id', this.channelId);
                data.append('name', this.channel.name);
                data.append('base_color', this.channel.baseColor);
                data.append('complementary_color', this.channel.complementaryColor);
                if (this.file){
                    data.append('avatar', this.file);
                }

                data.append('_method', 'PUT');

                axios.post(`/dashboard/channels/${this.channelId}`, data).then(resp => {
                    this.$parent.$emit('channel_updated', resp.data);
                }).catch(error => {
                    flash(error.response.data, 'danger', 'backEndStyle');
                });

                this.resetForm();
        }
    }
}
</script>

this is validation request for my image

public function rules()
{
    $avatrAttr = 'required|image|mimes:jpg,jpeg,png|max:50|dimensions:max_width=600,max_height=600';

    if($this->isMethod('POST')) {
        return [
            'avatar' => $avatrAttr,
        ];
    }  else {
        if ($this->has('avatar') && $this->hasFile('avatar')){
            return [
                'avatar' => $avatrAttr,
            ];
        }
    }
}

this is a Trait to handle image upload

public function verifyAndStoreImage($request, $oldImg = null, $fieldname = 'avatar', $directory) {

    if ($request->file($fieldname)->isValid()) {

        if ($oldImg != null) {
            $this->RemoveOldImg($oldImg);
        }

        return $request->file($fieldname)->store($directory, 'public');

    }

    return $oldImg;

}

the Controller for store and update

public function store(ChannelRequest $channelRequest, AvatarRequest $avatarRequest)
{
    $channel = Channel::create([
        'name' => $channelRequest->name,
        'bg_base_color' => $channelRequest->base_color,
        'bg_complementary_color' => $channelRequest->complementary_color,
        'avatar_path' => $this->verifyAndStoreImage($avatarRequest, null, 'avatar', 'avatars/channels')
    ]);

    return response($channel, 200);
}

/**
 * Update the specified resource in storage.
 *
 * @param ChannelRequest $channelRequest
 * @param Channel $channel
 * @return \Illuminate\Http\Response
 */
public function update(ChannelRequest $channelRequest, Channel $channel, AvatarRequest $avatarRequest)
{
    $channel->update([
        'name' => $channelRequest->name,
        'bg_base_color' => $channelRequest->base_color,
        'bg_complementary_color' => $channelRequest->complementary_color,
        'avatar_path' => $this->verifyAndStoreImage($avatarRequest, $channel->avatar_path, 'avatar', 'avatars/channels')
    ]);

    return response($channel->fresh(), 200);
}


via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire