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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

1356閲覧

Vue.js 配列から条件に合ったデータを抽出する方法について

sakananati

総合スコア1

Vue.js

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2022/11/21 05:47

編集2022/11/26 10:01

前提

Vue.jsでアプリを作成しており,行き詰ったため質問しています.
初めての質問ですので至らぬ点があると思います,指摘していただけたら幸いです.

実現したいこと

納期(order_due_date)と本日の日付を参照し,日付計算を行ってその日数の範囲に応じたCardコンポーネントを完了ボードに表示したい.

該当のソースコード

html

1<template> 2 <SwitchToggle /> 3 <meta name="viewport" content="width=device-width,initial-scale=1" /> 4 <div class="boardArea"> 5 <div class="board red"> 6 <p class="boardText">未完了</p> 7 <div class="cardredArea"> 8 <router-link 9 v-for="data in unfinishedCardDataSort" 10 :key="data" 11 :to="{ name: 'Detail', query: { order: data.order.id } }" 12 > 13 <Card 14 :customer-name="data.customer.name" 15 :order-due-date="data.order.order_due_date" 16 :product-number="data.product.number" 17 :product-name="data.product.name" 18 :product-quantity="data.product.quantity" 19 :process-name="data.process.name" 20 > 21 </Card> 22 </router-link> 23 </div> 24 </div> 25 <div class="board yellow"> 26 <p class="boardText">作業中</p> 27 <div class="cardArea"> 28 <router-link 29 v-for="data in workingCardData" 30 :key="data" 31 :to="{ name: 'Detail', query: { order: data.order.id } }" 32 > 33 <Card 34 :customer-name="data.customer.name" 35 :order-due-date="data.order.order_due_date" 36 :product-number="data.product.number" 37 :product-name="data.product.name" 38 :product-quantity="data.product.quantity" 39 :process-name="data.process.name" 40 > 41 </Card> 42 </router-link> 43 </div> 44 </div> 45 <div class="board green"> 46 <p class="boardText">完了</p> 47 <div class="cardArea"> 48 <router-link 49 v-for="data in completionCardDatafilter" 50 :key="data" 51 :to="{ name: 'Detail', query: { order: data.order.id } }" 52 > 53 <Card 54 :customer-name="data.customer.name" 55 :order-due-date="data.order.order_due_date" 56 :product-number="data.product.number" 57 :product-name="data.product.name" 58 :product-quantity="data.product.quantity" 59 :process-name="data.process.name" 60 > 61 </Card> 62 </router-link> 63 </div> 64 </div> 65 </div> 66</template> 67

javascript

1<script> 2import axios from 'axios' 3import Card from '../components/calendar_1day_card.vue' 4import SwitchToggle from '../components/SwitchToggle.vue' 5import moment from 'moment' 6const dateToday = moment(new Date()).format('yyyy-MM-DD') 7export default { 8 name: 'Kanban', 9 components: { 10 Card, 11 SwitchToggle, 12 }, 13 /** 14 filters: { 15 moment: function (date) { 16 return moment(date).format('yyyy-MM-DD') 17 }, 18 }, 19 */ 20 data() { 21 return { 22 cardData: [], 23 errorMsg: '', 24 unfinishedCardData: [], 25 workingCardData: [], 26 completionCardData: [], 27 } 28 }, 29 computed: { 30 unfinishedCardDataSort() { 31 return this.unfinishedCardData.slice().sort((a, b) => { 32 // 納期が早い順に並び替え 33 if (a.order.order_due_date !== b.order.order_due_date) 34 return a.order.order_due_date < b.order.order_due_date 35 ? -1 36 : a.order.order_due_date > b.order.order_due_date 37 ? 1 38 : 0 39 // 受注番号が小さい順に並び替え 40 if (a.order.id !== b.order.id) return a.order.id - b.order.id 41 // 作業番号が小さい順に並び替え 42 if (a.job_number !== b.job_number) return a.job_number - b.job_number 43 }) 44 }, 45 workingCardDataSort() { 46 return this.workingCardData.slice().sort((a, b) => { 47 // 納期が早い順に並び替え 48 if (a.order.order_due_date !== b.order.order_due_date) 49 return a.order.order_due_date < b.order.order_due_date 50 ? -1 51 : a.order.order_due_date > b.order.order_due_date 52 ? 1 53 : 0 54 // 受注番号が小さい順に並び替え 55 if (a.order.id !== b.order.id) return a.order.id - b.order.id 56 // 作業番号が小さい順に並び替え 57 if (a.job_number !== b.job_number) return a.job_number - b.job_number 58 }) 59 }, 60 completionCardDataSort() { 61 return this.completionCardData.slice().sort((a, b) => { 62 // 納期が早い順に並び替え 63 if (a.order.order_due_date !== b.order.order_due_date) 64 return a.order.order_due_date < b.order.order_due_date 65 ? -1 66 : a.order.order_due_date > b.order.order_due_date 67 ? 1 68 : 0 69 // 受注番号が小さい順に並び替え 70 if (a.order.id !== b.order.id) return a.order.id - b.order.id 71 // 作業番号が小さい順に並び替え 72 if (a.job_number !== b.job_number) return a.job_number - b.job_number 73 }) 74 }, 75 //納期(order_due_date)と操作日の日付を比較して7日以内の配列だけ出力する 76 completionCardDatafilter() { 77 return this.completionCardData.filter((a) => { 78 return moment(a.order.order_due_date).diff(dateToday, 'days') < 7 79 }) 80 }, 81 /** 82 completionCardData: function (order_due_date, today) { 83 return moment(order_due_date).diff(today, 'days') < 7 84 } 85 */ 86 }, 87 created() { 88 axios 89 .get(process.env.VUE_APP_API_SERVER_URL + '/v1/calendar/', { 90 params: { 91 worker: this.$route.query.worker, 92 }, 93 }) 94 .then((response) => { 95 console.log(response.data) 96 this.cardData = response.data 97 this.ArrayFilter() 98 }) 99 .catch((error) => { 100 console.log(error) 101 this.errorMsg = 'Error retrieving data' 102 }) 103 }, 104 methods: { 105 ArrayFilter: function () { 106 this.unfinishedCardData = this.cardData.filter(function (num) { 107 return num.status.id == 1 108 }) 109 this.workingCardData = this.cardData.filter(function (num) { 110 return num.status.id == 2 || num.status.id == 3 111 }) 112 this.completionCardData = this.cardData.filter(function (num) { 113 return num.status.id == 4 114 }) 115 }, 116 }, 117} 118</script> 119

変更,追加したコード

js

1const dateToday = moment(new Date()).format('yyyy-MM-DD') 2 3//納期(order_due_date)と操作日の日付を比較して7日以内の配列だけ出力する 4 completionCardDatafilter() { 5 return this.completionCardData.filter((a) => { 6 return moment(a.order.order_due_date).diff(dateToday, 'days') < 7 7 }) 8 },

試したこと

上記の機能を実装するために,まずはfilterを使って配列から条件に合ったデータを抽出したいと考え,日付を指定し,納期と日付が一致するプログラムを作ろうとしています.
現状,コードを追加してみてエラーは出ていないのですが,指定した日付以外の納期であるカードも表示されている現状でうまく動作しておらず原因もわからないので質問させていただきました.アドバイスをいただけたら幸いです.

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

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

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

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

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

guest

回答1

0

ベストアンサー

1.まず、template 内の

js

1 <div class="board green"> 2 <p class="boardText">完了</p> 3 <div class="cardArea"> 4 <router-link 5 v-for="data in completionCardData" 6以下略

の下から2番目の行を

js

1 v-for="data in completionCardDatafilter"

に変えます。


2.
しかし、上記に修正すると「完了」カテゴリにカードが表示されなくなります。
なぜカードが表示されないかというと、下記の算出プロパティ completionCardDatafilter の中にある filter 関数の引数に指定した関数は、常に undefined を返すからです。
結果、completionCardDatafilter は空の配列になるため、カードが表示されません。

js

1 // 質問文中のコードより引用。行末のコメントは筆者追記。 2 completionCardDatafilter() { 3 return this.completionCardData.filter((a) => { 4 a.order.order_due_date === '2021-01-22' 5 }) // この、filter関数に指定された引数関数は、常に undefined を返す。 6 },

この引数関数だけを取り出して書き換えると、下記とほぼ同義です。

js

1function(a) { 2 a.order.order_due_date === '2021-01-22'; // 単に比較してるだけ。 3 // returnされるのは、比較結果ではなく、undefined 4}

 

したがって、(1とともに)下記のように適切な判定結果を返すように修正してください。
【下記のように修正する】

js

1 completionCardDatafilter() { 2 return this.completionCardData.filter((a) => 3 a.order.order_due_date === '2021-01-22' 4 ); 5 },

または

js

1 completionCardDatafilter() { 2 return this.completionCardData.filter((a) => { 3 return a.order.order_due_date === '2021-01-22'; 4 }); 5 },

追記

コメントより

加えてもう一つ質問させていただきたいのですが,納期(order_due_date)と操作日の日付を比較して7日以内の配列だけ出力するプログラムを実装しようと変更したところ,completionCardDatafilterが機能していない?のか画像のようにすべてのカードを抽出してしまっている状態になっています.変更,追加したコードを追記してますので,お時間がある際にこちらに関してアドバイスいただけたら幸いです.(2022/11/24 04:14時点)

すべてのカードを抽出してしまっている原因として考えられるのは、

  • 抽出するデータが全部2021年となっている等、現実に即していないデータである可能性
  • momentのdiff関数の結果がうまく利用できていない

のいずれかもしくは両方であると考えられます。

1. テストデータの用意

まず、APIから取得するデータについては、「操作日」(moment(new Date()).format('yyyy-MM-DD') で取得できる文字列があらわす日付)に近い日付の、きちんとテスト可能なデータを用意してください。(さもなくば「const dateToday = moment(new Date()).format('yyyy-MM-DD')」の部分を、テストに整合する形に直して下さい)
(もしかしたら直されたうえで試されているのかもしれませんが、可能性として書かせていただきました)

2. moment の diff 関数

moment の diff 関数は、下記のようになっているようです。

js

1moment(A).diff(B, 'days') 2B を基準として、A が何日後であるか

仮にAPIが出力するデータのorder_due_date が2021-10-21等、2021年を表す場合

moment(a.order.order_due_date).diff(dateToday, 'days')

はマイナス数百日になるので、

moment(a.order.order_due_date).diff(dateToday, 'days') < 7

は常にtrueとなってしまいます。

3. 修正

以上を踏まえると、修正の内容としては、要件パターンに応じて下記のようになると思われます。(実際に動作確認する際は、APIが返すデータの order_due_date が操作日と近い日付になっていることが前提です。)
なお、下記で「操作日」とは「moment(new Date()).format('yyyy-MM-DD') で取得できる文字列があらわす日付」とします。

  • パターン①「納期(order_due_date)と操作日の日付を比較して7日以内の配列だけ出力する」の意味が、「納期(order_due_date)が、操作日の7日前から操作日の7日後までであるものを出力する」という意味である場合。

js

1 completionCardDatafilter() { 2 return this.completionCardData.filter((a)=> { 3 const daydiff = moment(a.order.order_due_date).diff(dateToday, 'days'); 4 return Math.abs(daydiff) <= 7; 5 }); 6 },

 

  • パターン②「納期(order_due_date)と操作日の日付を比較して7日以内の配列だけ出力する」の意味が、「納期(order_due_date)が、操作日から操作日の7日後までのものを出力する」という意味である場合。

js

1 completionCardDatafilter() { 2 return this.completionCardData.filter((a)=> { 3 const daydiff = moment(a.order.order_due_date).diff(dateToday, 'days'); 4 return daydiff >= 0 && daydiff <= 7; 5 }); 6 },
  • パターン③「納期(order_due_date)と操作日の日付を比較して7日以内の配列だけ出力する」の意味が、「納期(order_due_date)が、操作日の7日前から操作日までのものを出力する」という意味である場合。

js

1 completionCardDatafilter() { 2 return this.completionCardData.filter((a)=> { 3 const daydiff = moment(a.order.order_due_date).diff(dateToday, 'days'); 4 return daydiff >= -7 && daydiff <= 0; 5 }); 6 }, 7

@sakananati さん

投稿2022/11/21 10:39

編集2022/11/25 22:43
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

sakananati

2022/11/21 11:13

ご回答ありがとうございます,上記のようにコードを変更してみると完了ボードになにも表示されない状況です. 画像を追加しておきます.
退会済みユーザー

退会済みユーザー

2022/11/21 11:27 編集

確認なんですが、filter内での a.order.order_due_date は 確実に「yyyy-MM-dd」形式の文字列になっているのでしょうか?
sakananati

2022/11/21 11:46

度々ありがとうございます,apiに格納されているorder_due_dateの形式が「yyyy-MM-dd」の文字列なのでなっていると思われます. APIの画像も追加しておきます.
sakananati

2022/11/23 19:14

ありがとうございます,1,2のように修正すると指定した日付のみのデータを抽出することができました‼ 加えてもう一つ質問させていただきたいのですが,納期(order_due_date)と操作日の日付を比較して7日以内の配列だけ出力するプログラムを実装しようと変更したところ,completionCardDatafilterが機能していない?のか画像のようにすべてのカードを抽出してしまっている状態になっています. 変更,追加したコードを追記してますので,お時間がある際にこちらに関してアドバイスいただけたら幸いです.
sakananati

2022/11/26 01:01

想定していた機能を実装することができました,こちらの意図を汲み取った回答をありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問