0
votes

I use Laravel 8 inertia and vue

I want to update a post and I use this component in a main vue

<template>
<div class="container p-3 bg-green-600 flex flex-col">
    <div class="mb-8 text-2xl">{{ current_post.title }}</div>

    <div v-if="!edit" id="mode-display">
        <div v-html="compiledMarkdown" class="text-gray-700"></div>
    </div>
    <div v-else id="mode-edit">
        <form class="flex flex-col" @submit.prevent="updatePost">
        <input type="hidden" name="id" id="id" v-model="current_post.id">
            <button type="submit">Mettre à jour</button>
            <div class="flex">
                <div class="m-5 flex flex-col">
                    <label for="category">Catégorie du post</label>
                    <select class="px-2" name="category" id="category" v-model="current_post.category">
                        <option value="undefined">Sans</option>
                        <option value="Announcements">Annonce</option>
                        <option value="Narratives">Récit</option>
                        <option value="Pages">Page</option>
                    </select>
                </div>
                <div class="m-5 flex flex-col">
                    <label for="diaporama_dir">Dossier du diaporama</label>
                    <input name="diaporama_dir" id="diaporama_dir" type="text" placeholder="admin|1/Noël2019" v-model="current_post.diaporama_dir">
                </div>

            </div>
            <div class="flex">
                <div class="m-5">
                    <label for="beg_date">Date de début de l'événement</label>

                    <date-picker name="beg_date" format="YYYY-MM-DD" valueType="format" v-model="current_post.beg_date"></date-picker>
                </div>
                <div class="m-5">
                    <label for="end_date">Date de fin de l'événement</label>

                    <date-picker name="end_date" format="YYYY-MM-DD" valueType="format" v-model="current_post.end_date"></date-picker>
                </div>
                <div class="m-5">
                    <label for="close_date">Date de clôture des inscriptions</label>

                    <date-picker name="close_date" format="YYYY-MM-DD" valueType="format" v-model="current_post.close_date"></date-picker>
                </div>
                <div class="m-5 flex flex-col">
                    <label for="receive_registration">Accepte des inscriptions</label>
                    <select class="px-2" name="receive_registration" id="receive_registration" v-model="current_post.receive_registration">
                        <option value="false">Non</option>
                        <option value="true">Oui</option>
                    </select>
                </div>
            </div>

            <input class="p-5 mb-5 text-xl" type="text" v-model="current_post.title" />
            <div class="m-5 flex flex-col">
                <label for="abstract">Résumé</label>
                <textarea class="markdown bg-green-500 text-gray-100" name="abstract" id="abstract" v-model="current_post.abstract" rows="3"></textarea>
            </div>
            <div class="m-5 flex flex-col">
                <label for="body">Résumé</label>
                <textarea class="markdown bg-green-500 text-gray-100" name="body" id="body" v-model="current_post.body" rows="50"></textarea>
            </div>
        </form>
    </div>
</div>
</template>

<script>
import DatePicker from 'vue2-datepicker';
import 'vue2-datepicker/index.css';
import 'vue2-datepicker/locale/fr';

import marked from 'marked';
export default {
    name: "PostDetails",
    props: ["current_post", "edit"],
    components: {
        DatePicker
    },
      data() {
        return {
            
            form:{
                id:null,
                title: null,
                abstract: null,
                body: null,
                category: null,
                beg_date: null,
                end_date: null,
                close_date : null,
                receive_registration : null,
                diaporama_dir: null
            }
        };
    },
    methods:{
      updatePost(){
           this.$inertia.post('/post', this.form);
      }
    },
    computed: {
        compiledMarkdown: function () {
            if (this.current_post) {
                //transform markdown to html
                return marked(this.current_post.body);
            }
        },
        mounted() {},
    }
};
</script>

When displaying this template with the form , I receive a correct post and its values are correctly displayed in the various input fields.

My controller, at the moment is very simple :

public function Update(Request $request)
    {
       dd($request);
    }

On submitting this form the dd outputs this:

Illuminate\Http\Request {#43 ▼
  #json: Symfony\Component\HttpFoundation\ParameterBag {#35 ▶}
  #convertedFiles: null
  #userResolver: Closure($guard = null) {#342 ▶}
  #routeResolver: Closure() {#351 ▶}
  +attributes: Symfony\Component\HttpFoundation\ParameterBag {#45 ▶}
  +request: Symfony\Component\HttpFoundation\ParameterBag {#35 ▼
    #parameters: array:10 [▼
      "id" => null
      "title" => null
      "abstract" => null
      "body" => null
      "category" => null
      "beg_date" => null
      "end_date" => null
      "close_date" => null
      "receive_registration" => null
      "diaporama_dir" => null
    ]
  }
  +query: Symfony\Component\HttpFoundation\InputBag {#51 ▶}
  +server: Symfony\Component\HttpFoundation\ServerBag {#47 ▶}
  +files: Symfony\Component\HttpFoundation\FileBag {#48 ▶}
  +cookies: Symfony\Component\HttpFoundation\InputBag {#46 ▶}
  +headers: Symfony\Component\HttpFoundation\HeaderBag {#49 ▶}
  #content: "{"id":null,"title":null,"abstract":null,"body":null,"category":null,"beg_date":null,"end_date":null,"close_date":null,"receive_registration":null,"diaporama_dir ▶"
  #languages: null
  #charsets: null
  #encodings: null
  #acceptableContentTypes: null
  #pathInfo: "/post"
  #requestUri: "/post"
  #baseUrl: ""
  #basePath: null
  #method: "POST"
  #format: null
  #session: Illuminate\Session\Store {#392 ▶}
  #locale: null
  #defaultLocale: "en"
  -preferredFormat: null
  -isHostValid: true
  -isForwardedValid: true
  -isSafeContentPreferred: null
  basePath: ""
  format: "html"
}

It seems to me I am obeying the guidance given in this page https://inertiajs.com/forms but why on earth the form's value are not uploaded to the server?

2
dd($request); to dd($request->all()); try thisKamlesh Paul
Thank you. I see now. Probably I am a bit tired and confused as I am new to everything . I have another question about passing the existing post to initialize the form. This template is for a single post component I name "details" that is used in a global vue for all posts.I should normally pass it in data() {return form:{ id=null, title=this.details.title ....} but as details (that is a particular post in the list of posts) is lazily loaded, data is not refresh when I need it. In addition using v-model="something" doesn't allow me to initialize an input field. I will post another question.Meaulnes

2 Answers

1
votes

In your code, you're sending the form object (which is full of null values). For now, you can fix it like this:

updatePost () {
  this.$inertia.post('/post', this.current_post);
}

But probably you're having a vue-warn saying that it's not recommended to edit a prop. so I suggest also the following:

  • you receive the post prop as current_post
  • you should copy it to your form object (on mounted)
  • link all of your form inputs to the form object instead of current_post
0
votes

I can not add a comment yet but wanted to add that if You clone a reactive object You are not actually copying it. The cloned object is the same as the original and modifying this new object modifies the original object too and vice versa so basically You are doing exactly the same thing that got You in trouble at the first place: Modifying properties.

Vue states that You should not modify a property because if a parent component modifies a prop your changes are gone.

Lodash clonedeep creates a new object from the property:

this.items = _.cloneDeep(this.data);