質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

Q&A

解決済

1回答

2071閲覧

Laravel + Vue.js +axios でデータがPOSTできない。

tkm0604

総合スコア552

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

0グッド

0クリップ

投稿2021/12/19 08:51

編集2021/12/19 08:53

Laravel + Vue.js +axios で 2つの関数、saveCanvas()と、postArticle()を
<button @click="saveCanvas('preview');postArticle()">で、POSTを実行したいです。
それぞれの関数は以下のように書いています。

<canvas>タグに文字を描画してaxios経由でPOSTする関数

javascript

1 // Canvasのデータをblob化 axiosでPOST 2 saveCanvas: function (canvas_id) { 3 const type = "image/png"; 4 const canvas = document.getElementById(canvas_id); 5 const dataurl = canvas.toDataURL("image/jpeg", 0.85); 6 const bin = atob(dataurl.split(",")[1]); 7 const buffer = new Uint8Array(bin.length); 8 for (let i = 0; i < bin.length; i++) { 9 buffer[i] = bin.charCodeAt(i); 10 } 11 12 const blob = new Blob([buffer.buffer], { type: type }); 13 14 const data = new FormData(); 15 data.append("images", blob, "png"); 16 17 axios 18 .post("/api/images", data) 19 .then((res) => { 20 console.log("success"); 21 }) 22 .catch((error) => { 23 new Error(error); 24 }); 25 26 },

inputタグ name=titleとcommentをaxios経由でPOSTする関数

javascript

1 postArticle: function (){ 2 var article = { 3 "title": this.title, 4 "comment": this.comment, 5 }; 6 7 axios 8 .post("/api/images", article) 9 .then((res) =>{ 10 console.log("success2"); 11 }) 12 .catch((error) => { 13 new Error(error); 14 }); 15 },

上記2つの関数、それぞれ単体ではDBに保存(POST)ができるのですが、buttonに2つの関数をまとめると、postArticle()関数からデータが送れません。(title とcommentがNullとなる)

axios経由で2つの関数をPOSTする事はできないのでしょうか?

また、その場合、どのようにまとめればいいのかわかりません。
アドバイスお願いします。

Vue.jsの単一コンポーネントは以下のように書いています。

javascript

1<template> 2 <div> 3 <!-- 画像エリア --> 4 <div id="image_area"> 5 <canvas ref="preview" id="preview"></canvas> 6 <input type="file" name="image" accept="image/*" ref="selectimage" @change="previewImage"/> 7 </div> 8 <p> 9 <input type="text" id="canvas_text" value="" /> 10 <button type="button" @click="drawText('preview', 'canvas_text')"> 11 文字を描く 12 </button> 13 </p> 14 15 <!-- タイトル入力 --> 16 <div> 17 <input id="title" v-model="title" type="text" name="title" placeholder="タイトル"> 18 </div> 19 <div> 20 <!-- コメント入力エリア --> 21 <textarea id="comment" name="comment" cols="30" rows="10" v-model="comment" placeholder="コメント入力"></textarea> 22 </div> 23 <button @click="saveCanvas('preview');postArticle()">アップロード</button> 24 25 </div> 26</template> 27 28<script> 29export default { 30 methods: { 31 // canvasの画像をinput type="file"にプレビュー 32 previewImage: function () { 33 let file = this.$refs.selectimage.files; //ファイル情報の取得 34 const canvas = this.$refs.preview; //canvasタグ 35 const fileReader = new FileReader(); 36 fileReader.onload = function () { 37 const ctx = canvas.getContext("2d"); 38 const image = new Image(); 39 image.src = fileReader.result; 40 image.onload = function () { 41 canvas.width = image.width; 42 canvas.height = image.height; 43 ctx.drawImage(image, 0, 0); 44 }; 45 }; 46 fileReader.readAsDataURL(file[0]); 47 }, 48 49 //キャンバスに文字を描く 50 drawText: function (canvas_id, text_id) { 51 const canvas = document.getElementById(canvas_id); 52 const ctx = canvas.getContext("2d"); 53 const text = document.getElementById(text_id); 54 //文字のスタイルを指定 55 ctx.font = "32px serif"; 56 ctx.fillStyle = "#404040"; 57 //文字の配置を指定(左上基準にしたければtop/leftだが、文字の中心座標を指定するのでcenter 58 ctx.textBaseline = "center"; 59 ctx.textAlign = "center"; 60 //座標を指定して文字を描く(座標は画像の中心に) 61 const x = canvas.width / 2; 62 const y = canvas.height / 2; 63 ctx.fillText(text.value, x, y); 64 }, 65 66 // Canvasのデータをblob化 axiosでPOST 67 saveCanvas: function (canvas_id) { 68 const type = "image/png"; 69 const canvas = document.getElementById(canvas_id); 70 const dataurl = canvas.toDataURL("image/jpeg", 0.85); 71 const bin = atob(dataurl.split(",")[1]); 72 const buffer = new Uint8Array(bin.length); 73 for (let i = 0; i < bin.length; i++) { 74 buffer[i] = bin.charCodeAt(i); 75 } 76 77 const blob = new Blob([buffer.buffer], { type: type }); 78 79 const data = new FormData(); 80 data.append("images", blob, "png"); 81 82 axios 83 .post("/api/images", data) 84 .then((res) => { 85 console.log("success"); 86 }) 87 .catch((error) => { 88 new Error(error); 89 }); 90 91 }, 92 93 94 //inputタグ name=title,commentをPOST 95 postArticle: function (){ 96 var article = { 97 "title": this.title, 98 "comment": this.comment, 99 }; 100 101 axios 102 .post("/api/images", article) 103 .then((res) =>{ 104 console.log("success2"); 105 }) 106 .catch((error) => { 107 new Error(error); 108 }); 109 }, 110 111 112 }, 113}; 114</script> 115 116

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

JavaSCript

1var that = this 2axios 3 .post("/api/images", data) 4 .then((res) => { 5 console.log("success"); 6 that.postArticle(); 7 }) 8 .catch((error) => { 9 new Error(error); 10 });

はどうですか?

もしできなかったら
二つ関数を実行する関数をまた作り上げればどうですか?

JavaScript

1upload: function(){ 2 saveCanvas('preview'); 3 postArticle() 4}

投稿2021/12/19 10:29

編集2021/12/20 15:32
skys215

総合スコア910

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tkm0604

2021/12/19 12:51 編集

コメントありがとうございます。 2つとも試したのですが、 一つ目にご提案は以下のように書いたのですが、titleとcommentがやはりNullになります。 <button @click="saveCanvas('preview')">アップロード</button> <script> export default { methods: { // Canvasのデータをblob化 axiosでPOST saveCanvas: function (canvas_id) {   ///中略//// const data = new FormData(); data.append("images", blob, "png"); var that = this axios .post("/api/images", data) .then((res) => { console.log("success"); that.postArticle(); }) .catch((error) => { new Error(error); }); }, //inputタグ name=title,commentをPOST postArticle: function (){ var article = { "title": this.title, "comment": this.comment, }; }, </script>
tkm0604

2021/12/19 12:52 編集

2つ目のご提案は、以下のように書いたのですが、 upload:()=>{}内の saveCanvas('preview');で saveCanvas is not defined となります。 <button @click="upload()">アップロード</button> <script> export default { methods: { // Canvasのデータをblob化 axiosでPOST saveCanvas: function (canvas_id) {    //中略// }, //inputタグ name=title,commentをPOST postArticle: function (){    //中略// }, //2つの関数をまとめる upload:()=>{ saveCanvas('preview'); postArticle(); }, }, }; </script>
skys215

2021/12/19 14:46

一つ目に対して、titleとcommentはvueのdataに定義してありますか? 二つ目に対して、this.saveCanvas('preview'); this.postArticle();で試してください。
tkm0604

2021/12/20 06:39

コメントありがとうございます。一つ目に対して、 data(){ return { title:"", comment:"" } }, を追記しても、、titleとcommentがやはりNullになります。 crhomeのデベロッパーツールは「status of 500」のエラーが出ています。 二つ目に対して、this.を追加しましたが、結果変わらず、 upload:()=>{}内の saveCanvas('preview');で saveCanvas is not defined となります。 1つ目の提案はグローバルスコープ内で関数postArticle();をsaveCanvas('preview'); 内の変数thatに渡して、saveCanvas('preview');のaxios内で同時にPOSTするようにし@click="saveCanvas('preview');postArticle()でPOST 2つ目の提案は2つの関数を一つの関数upload()にまとめて @click="upload()でPOST といいう趣旨だと思うのですが、いずれもうまくいきませんでした。 おかしなことがあればご指摘くださいl
skys215

2021/12/20 16:02

https://jsfiddle.net/skys215/gbysracd/2/ JsFiddleでテストしました。 一つ目は試しましたけど、nullにはなりませんでした。 二つ目はupload:()=>{ だとthisは上書きされますので、upload: function() {にしないとthisは使えません。
tkm0604

2021/12/21 05:41

ありがとうございます!確認します!!
tkm0604

2022/01/21 05:30

返信遅くなりすみません。本当にうまくいかなくて時間がかかったのですが、POSTできなかった原因は、公式ドキュメントに、「Vue が適切な this の値を束縛するのを防ぐため、 methods を定義する際にはアロー関数を使うのは避けるべきです。」とあるように、アロー関数を使用していたのが原因でした。 アロー関数で書いていた箇所を修正後、教えていただいた2つの方法でもPOSTできました。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問