wadigchan
@wadigchan

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

axios通信エラー

解決したいこと

laravelを使ったブログサイトを作っています。
現在、ブログ編集画面を作っていて、あとは更新ボタンを押してブログが更新されれば完成なのですが、そこでエラーが出ました。

発生している問題・エラー

Undefined array key \"id\" 

該当するソースコード

エラー箇所
$post = Post::find($inputs['id']);
PostController
public function update(PostRequest $request, int $id)
    {
        $inputs = $request->all();

        \DB::beginTransaction();

        $post = Post::find($inputs['id']);      // エラー箇所

        $post->fill([
            'title' => $inputs['title'],
            'content' => $inputs['content'],
            'is_published' => $inputs['is_published'],
        ]);

        $post->tags()->detach();

        preg_match_all('/([a-zA-Z0-90-9ぁ-んァ-ヶー一-龠]+)/u', $request->tagCategory, $match);;

        $tags = [];

        foreach ($match[1] as $tag) {
            $found = Tag::firstOrCreate(['tag_name' => $tag]); 

            array_push($tags, $found);
        }

        $tag_ids = [];

        foreach ($tags as $tag) {
            array_push($tag_ids, $tag['id']);
        }

        $post->save();
        $post->tags()->syncWithoutDetaching($tag_ids);

        if ($request->image != null) {
            if ($request->image->isValid()) {
                $image = new Image;
                $filename = $request->image->store('public/image');
                $image->image = basename($filename);
                $image->post_id = $post->id;
                $image->save();
            }
        }

        \DB::commit();

        if ($post->is_published == 1) {
            \Session::flash('err_msg', 'ブログを更新しました');
        } else {
            \Session::flash('err_msg', 'ブログをアーカイブに保存しました');
        }
    }
EditComponent.vue
methods: {
        
....省略

        update(post) {
            if (window.confirm("更新してよろしいですか?")) {
                const content = this.$refs.toastUiEditor.invoke("getMarkdown");

                if (content === "") {
                    alert("本文が入力されていません");
                    return;
                } else if (this.title === "") {
                    alert("タイトルが入力されていません");
                    return;
                } else if (this.title.length > 255) {
                    alert("タイトルは255文字以内にしてください");
                    return;
                } else if (this.is_published === "") {
                    alert("公開設定を選択してください");
                    return;
                }

                const id =this.post.id;

                const data = new FormData();
                data.append("imageData", this.uploadFile);
                data.append("title", this.title);
                data.append("content", content);
                data.append("is_published", this.is_published);
                data.append("tagCategory", this.tagCategory);
                data.append("id", id);

                axios
                    .put("/posts/" + id, data)
                    .then((res) => {
                        console.log(res);
                        this.posts = res.data.posts;
                        window.location = "/";
                    })
                    .catch((error) => {
                        console.log(error);
                        console.log(error.response.data);
                    });
            } else {
                return false;
            }
        },
    },

自分で試したこと

https://teratail.com/questions/347238
"id"をもたない配列があることが原因のようですが、コントローラのエラー箇所で使われるidに配列が関係しているのかがよく分からず対処法に困っています。

0

1Answer

$inputs = $request->all();
$inputs['id'];

allメソッドは全入力を配列で取得できるので$inputsは配列になります。
エラーメッセージからすると$inputsに添字idが無いということです。

ちなみにですがidは$idに入ってるのではないでしょうか?
ルーティングが/posts/{id}のようになっていれば、updateメソッドの引数として渡されてると思います。

0Like

Comments

  1. @wadigchan

    Questioner

    いつもありがとうございます。
    確かに $request->all(); はddした時いつも配列で表示されてました、、。
    ルーティングも /posts/{id} になっているので、$idで渡されているため、
    data.append("id", id); もいらなかったんですね。

    $post = Post::find($inputs['id']);

    $post = Post::find($id);
    これに変更したところうまく行きました。

    ただ、次にis_publishedがnullだというエラーが出まして、確認したところ、他のタイトルやカテゴリもコントローラに届いていませんでした。
    ただ、vueで

    const data = new FormData();
    data.append("title", this.title);
    data.append("content", content);
    data.append("tagCategory", this.tagCategory);
    data.append("imageData", this.uploadFile);
    data.append("is_published", this.is_published);

    const data = {
    title: this.title,
    content: content,
    tagCategory: this.tagCategory,
    imageData : this.uploadFile,
    is_published: this.is_published,
    };
    このように変更したところ解決したのですが(厳密にいうと画像だけ送られなくなってしまい解決ではないのですが)、これで解決した理由がよくわかりません。
    FormDataの形式ではdataはコントローラに送られないのでしょうか?

  2. vueやaxiosには詳しくないので直接の回答はできないのですが、
    まずはリクエストにどんな違いがあるのかを確認するのが良いと思います。

    また「axios formdata」で少し検索したところ、配列やファイルを送信する場合は工夫が必要みたいです。
  3. @wadigchan

    Questioner

    工夫が必要なんですね...汗
    FormDataじゃない方法で画像も送れるようになりました!

    回答ありがとうございました。

Your answer might help someone💌