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

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

ただいまの
回答率

90.50%

  • JavaScript

    20369questions

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

  • jQuery

    8147questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • CakePHP

    2519questions

    CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

  • Ajax

    1326questions

    Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

cakephp2系 非同期通信にて取得した値をリアルタイムに表示させたい。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,552

milkif

score 10

前提・実現したいこと

非同期通信にて取得した値をDBに登録し、送信後の値をリアルタイムに表示させたい。

発生している問題・エラーメッセージ

非同期通信にてモーダルを閉じる処理、次の動画を呼び出す処理及びDBにデータを保存するまでは実行できましたが、送信後の値(afterP)が送信前(beforeP)の値となってしまう。
手動でブラウザのリロードを行うと送信後の値(afterP)を取得できるが、元の動画に戻ってしまう。

dataType:"json"にすると送信時にアラートが表示
Error : SyntaxError: Unexpected end of JSON inputが出てしまい次に進みません。
index.ctpのJSON.encodeJSON.parseを外すと上記エラーは出ませんが、videosの値をjsファイルに渡す方法がわからず外せていません。

該当のソースコード

Point.php
class Point extends AppModel {    
    public function sumByUserId($userId) {
    $data = $this->find('all',
        array(
            'conditions'=> array('user_id' => $userId),
            'fields'    => array('sum(point) as sumPoints'),
        )
    );
    return $data['0']['0']['sumPoints'];
    }
}
PointsController
他のコード省略
public function beforeFilter() {
    parent::beforeFilter();
      $userId = $this->Auth->user('id');
        $beforeP = $this->Point->sumByUserId($userId);
        $this->set(compact('beforeP'));
}

public function index() {
    $this->set('videos', $this->Video->find('all'));
}

public function addPoint() {
        if (!$this->request->is('ajax')) {
            throw new BadRequestException();
        }
        $userId = $this->Auth->user('id');
        $data = array(
            'Point' => array(
                'user_id' => $this->Auth->user('id'),
                'point' => $this->request->data['point'],
            )
        );
        $this->Point->create();
        $this->Point->save($data);

        $afterP = $this->Point->sumByUserId($userId);
        $this->viewClass = 'json';
        $this->set(compact('afterP'));
        $this->set('_serialize', array('afterP'));
    //$this->set('_serialize',(res));のまま使ってしまい気付ずこの時間になってしまいました。
        }
point.js
他のコード省略
$(".send").on("click",function(){
    $.ajax({
    type: "POST",
    url: "/aaa/bbb/addPoint",
    dataType: "json", //やっとjsonで動きました!有難うございます。
    data: {
    "point": point
        },
    success: function(res) {
      //モーダルを閉じる処理;
      //次の動画を呼び出す処理;
      $('#sumPoints').text(res.afterP);
      },
      error: function(XMLHttpRequest, textStatus, errorThrown) {
    alert('Error : ' + errorThrown);
      }
   });
   return false;
   }
});
index.ctp
他のコード省略
<p>送信前:<?php echo $beforeP; ?> pt</p>
<p>送信後:<span id="sumPoint"></span> pt</p>

<?php
function json_safe_encode($data){
    return json_encode($data, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
}

$videos = json_safe_encode($videos);
//$afterP = json_safe_encode($afterP);(削除)
 ?>

<script>
var videos = JSON.parse('<?php echo $videos; ?>');
//var afterP = JSON.parse('<?php echo $afterP; ?>');(削除)
</script>

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

より詳細な情報
XAMPP 5.6.14-0   
cakephp-2.7.8   
jquery 1.11.0 
10.0.17-MariaDB

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

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

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

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

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

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

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

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

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

exitはPHPスクリプト自体を終了させる言語構造で、それ以降の処理は行われません。
削除するか、処理を抜ける目的ならreturnに置き換えてみてください。

また、PointsController::indexがポイント操作も請け負うのは不自然で
その部分は別アクションや別コントローラに切り分けたほうが良いかもしれません。
そのほうが問題箇所の特定もしやすくなるはずです。

PHP: exit - Manual
http://php.net/manual/ja/function.exit.php

追記 2016-06-03 18:15

ポイントの合計を求める処理は複数個所で使われそうなので、Pointモデルのメソッドに
してもいかもしれません。

class Point extends AppModel {
    //略
    public function sumByUserId($userId) {
        $data = $this->find('all',
            array(
                'conditions'=> array('user_id' => $userId),
                'fields'    => array('sum(point) as sumPoints'),
            )
        );
        return $data['0']['0']['sumPoints'];
    }
}

//コントローラ側で使う時はこんな感じ
$userId = $this->Auth->user('id');
$afterP = $this->Point->sumByUserId($userId);

ポイント加算アクションの例です。indexアクション内のajax対処部分を
抜き出しただけなので、問題の解決につながるかはまだ分かりません。

public function add() {
    if (! $this->request->is('ajax')) {
        //ajax以外なら例外を投げる
    }
    $userId = $this->Auth->user('id');
    $data = array(
        'Point' => array(
            'user_id' => $userId,
            'point'   => $this->request->data['point'],
        )
    );
    $this->Point->create();
    $this->Point->save($data);

    $afterP = $this->Point->sumByUserId($userId);
    $this->viewClass = 'json';
    $this->set(compact('afterP'));
    $this->set('_serialize','res');
}

ポイントの加算に対応するアクションがindexからaddに変わったので
ajaxのリクエスト先も変更します。

$.ajax({
  type: "POST",
  url: ""


urlを /CakePHPディレクトリのパス/points/addに変更
環境によってはちょっと違うかもしれません。ブラウザでF12を押してコンソールを出し、
いろいろ試しながら確認してみてください。

addアクションからレスポンスが返ってくるようになれば、
indexアクション内のajaxに関わるコードは削除してしまっても構いません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/02 23:33

    nnssnさん回答有り難うございます。exit;はMySQL接続を切る役割だと勘違いしていました。有難うございます。
    ポイント操作の切り分け方ですが

    beforeFilter( ){
    ・現在のポイント合計を呼び出す処理
    ・現在のポイント合計を変数にする処理
    }

    index( ){
    ・登録されている動画を呼び出す処理
    ・ajaxでdataを受け取る処理
    ・そのdataをDBに保存する処理
    }

    other action( ){
    ・DBからポイント合計を呼び出す処理
    ・ポイント合計を変数にする処理
    }

    切り分けの考え方はよろしいでしょうか?
    その際、index( )でajaxお処理をした後に、自動でother action( )の処理をさせるのは
    redirectを使って連携させるのでしょうか?

    トンチンカンな質問かも知れませんが、お時間のある時で構わないのでアドバイスをお願いいたします。


    キャンセル

  • 2016/06/03 18:02 編集

    > その際、index( )でajaxお処理をした後に、自動でother action( )の処理をさせるのは
    > redirectを使って連携させるのでしょうか?

    今はindexアクションが状況に応じてHTMLを返したり、ポイント数をjsonで
    返したりしています。多分この、状況によって役割が変わるという部分が
    分かりにくさにつながっているのだと思います。

    ajax > index > other という流れをイメージされていると思うのですが、
    ajax > other のみで完結させたほうが良いでしょう。

    ・indexアクションはindexの描画だけを担当する、Ajaxの事は考えない
    ・「ポイントを追加して返す」アクションはそれだけをする、HTMLの事は考えない
    と分ければ処理内容は追いやすくなるはずです。

    続きます。 < コメント欄だとコードが見づらいので回答を編集しました。

    キャンセル

  • 2016/06/03 23:09

    貴重なお時間を頂き回答下さり誠にありがとうございました。
    とても分かりやすく、綺麗なコードと丁寧なご説明のおかげで、やっとやっと出来ました!
    感謝し尽くしても足りないくらい本当にありがとうございました。
    嬉しくてたまりません。質問のコードは動かせたコードに修正いたしました。
    本当にありがとうございました。

    キャンセル

  • 2016/06/04 18:22

    おお...addアクションの最後間違ってましたね、失礼しました。
    問題のほうが解決したようで良かったです。作品完成までがんばってください。

    キャンセル

  • 2016/06/04 18:51

    本当にありがとうございました!

    キャンセル

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

  • JavaScript

    20369questions

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

  • jQuery

    8147questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • CakePHP

    2519questions

    CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

  • Ajax

    1326questions

    Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。