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

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

新規登録して質問してみよう
ただいま回答率
87.20%

解決済

ajaxで取得したデータを全て表示できない

suika11
suika11

総合スコア166

3回答

0評価

1クリップ

416閲覧

投稿2022/04/13 01:52

編集2022/04/15 07:37

無限スクロールを作っていますが、ajaxで取得したデータを元に要素を生成したいのですが、毎回1つか2つ生成されず抜けがあります。データは全てサーバーから取得できているためjs内に問題があります。

追記
TypeError: Cannot read properties of undefined (reading 'user_id')とエラーを吐きました。「 this.AjaxCommentUser(data.comments[i].user_id)」が問題の箇所ですが、data.commentsの各オブジェクト内にuser_idはあるのでなぜこのようなエラーを返すのかわかりません

該当のソースコード

index.blade.php

methods: { AjaxAddContent() { if (!this.itemLoading) { //読み込み中は読み込めないようにする this.itemLoading = true // 追加コンテンツ fetch('/ajax/getSidebarComment', { method: 'POST', body: new URLSearchParams({ count: this.page }), headers: { 'X-CSRF-TOKEN': gid("jsHandOvers").dataset.csrf }, }).then(res => { return res.json(); }).then(data => { // console.log(data.comments.length) let AddContent = ""; for (let i = 0; data.comments; i++) { this.AjaxCommentUser(data.comments[i].user_id) .then(user => { this.AjaxCommentArticle(data.comments[i].article_id) .then(article => { ↓ここで要素を作るがなぜか抜けがある AddContent += `<div class="streamTile"><div><a href="/articles/${data.comments[i].article_id}?id=${data.comments[i].id}"></a><div class="userInfo"><a href="/users/${user.userID}"><div class="userIcon"><img src="/storage/${user.icon || 'icon/initial.jpeg'}" class="icon"></div><div><div class="userName _ellipsised">${user.name || '氏名'}</div><div class="userID">@${user.userID}</div></div></a><div class="commentDate">${data.comments[i].updated_at}</div></div><div class="commentArea"><div class="comment _ellipsised">${data.comments[i].body || ''}</div></div><div class="titleArea"><div class="title _ellipsised">${article.title}</div></div></div></div><div class="tileSeparator"></div>`; if (data.comments.length - 1 === i) { $('#timelineContainer').append(AddContent); this.page += data.comments.length } }).catch(err => {}); }).catch(err => {}); } }).catch(err => { // console.log(err.response) this.itemLoading = false }).finally(hoge => { this.itemLoading = false }); } }, async AjaxCommentUser(user_id) { let res = await fetch(`/ajax/users/${user_id}`, { method: 'POST', headers: { 'X-CSRF-TOKEN': gid("jsHandOvers").dataset.csrf }, }); let data = await res.json(); return data.user; }, async AjaxCommentArticle(article_id) { let res = await fetch(`/ajax/articles/${article_id}`, { method: 'POST', headers: { 'X-CSRF-TOKEN': gid("jsHandOvers").dataset.csrf }, }); let data = await res.json(); return data.article; }, } }).mount("#timelineContainer");

試したこと

「ajax 全て表示」等で検索

補足情報(FW/ツールのバージョンなど)

PHP 8.1.1
Laravel 8.79.0

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

SurferOnWww

2022/04/13 01:58

await が抜けてるところがあるのでは?
hoshi-takanori

2022/04/13 02:02

catch(err => {}) でエラーが握りつぶされてるかも?
yambejp

2022/04/13 02:21

ちなみにfetchはXMLHttpRequestではないのでajaxと呼ぶべきかどうかは判断が分かれます
suika11

2022/04/13 03:45

SurferOnWwwさん どこかが非同期処理になってしまっているようですね hoshi-takanoriさん その中でconsole.log(err)したら「TypeError: Cannot read properties of undefined (reading 'user_id')」と返ってきました yambejpさん ありがとうございます。
hoshi-takanori

2022/04/13 06:55

int32_t さんの回答にある通り、ループの終了条件がおかしいために無限ループになり、data.comments の個数よりも i が大きくなると data.comments[i] が undefined なので user_id にアクセスできなくてエラーになってるのでしょうね。が、表示漏れの原因はそれではなく、非同期で結果が返ってくる順番の問題だと思います。 ちなみに、user や article を一つ一つ分けて取得するのは効率が悪いので、API を修正できるなら getSidebarComment でまとめて返すようにした方がいい気がします。
suika11

2022/04/14 22:36

hoshi-takanori ありがとうございます。getSidebarCommentで全て取得したら思い通りの処理を実現できました

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る