2016-12-11 5 views
1

私はショッピングカートのアプリケーションで作業しています。ユーザーはローカルストレージに保存されているカートにアイテムを追加します。ユーザーがカートにアイテムを追加している別のページに移動すると、カートに追加したアイテム(ローカルストレージ)がページに挿入される必要があります。私はハンドルバーを使用して自分のページのテンプレートを構築しています。NodeJS/ExpressJSはルートを作成し、get/postリクエストのページを作成し、Ajaxはクライアントとサーバーとの間でリクエストを送信します。ページ上のJavascriptを使用してAjaxリクエストを成功させる方法

現在、ユーザがビューカートのページにアクセスしたときに、最初に動作しましたが、直ちに「エラー:送信後にヘッダーを設定できません。」というメッセージが表示されます。これはまた、かなりハッキリ/悪い方法で達成されています。ここでは、まず始めに

は、ビューカートページの最初の取得のために私のコードです:

viewCart: function(req, res){ 
    if(req.session.success){ 
    res.render('base', {title: 'View Cart', userNav: true, checkoutNav: true, viewCart: true, cartIcon: true, js:js}); 
    }else{ 
     res.render('base', {title: 'View Cart', userNav: true, viewCart: true, cartIcon: true, js:js}); 
    } 
}, 

これはそれでローカルストレージからのデータなしでページをレンダリングしています。 ID「viewCartTable」がと実行しているとき、私は、この機能を見てきた私のJavaScriptで

<div id="viewCartTable"></div> 

:ここ は、ローカルストレージからのデータを取り込むために私が呼​​び出していた変数のHTMLであり、 AJAXリクエスト:

if(document.getElementById("viewCartTable")){ 
    var data = localStorage.getItem("Products"); 
    Ajax.sendRequest("/user/viewCart", function(res){ 
    responseArr = res.responseText.split('^^^'); 
    if(responseArr[0] === "error"){ 
     console.log("error"); 
     setTimeout(function(){('','#000',false)}, 1500); 
    }else if(responseArr[0] === "Success"){ 
     console.log("Success"); 
     var tableCart = document.getElementById("viewCartTable"); 
     tableCart = tableCart.innerHTML = responseArr[1]; 
    }}, data); 
} 

このAjaxリクエストは、ビューカートページのポストに送信され、私は問題が実際に展開された場合、これはかもしれ信じています。彼はポストです:

viewCartPost: function(req, res){ 
     var data = JSON.parse(req.body.data); 
     console.log(data); 
     var keys = Object.keys(data); 
     //console.log(keys); 
     for(var i = 0; i<keys.length; i++){ 
     var productId = keys[i]; 
     Product.find({productId: productId}).select({productId : 1, addProductGroupName: 1, productName: 1, productPrice: 1, productDescription: 1, filePath: 1}).exec(function(err, cartProducts){ 
     if(err){ 
      console.log(err); 
      res.send("error"); 
     }else{ 
      res.send("Success^^^"+cartProducts); 
     } 
     }); 
     console.log(productId); 
     } 
    }, 

これは、クライアント側から送信されたローカルストレージの情報を取得し、保存され、ローカルストレージに送信される商品コードと一致した製品とそれらの情報を見つけることです。

このように、今回のセットアップは初めてです。ページの最初の訪問は、ローカルストレージ内の製品のデータを印刷するだけでなく、「成功」をフロントエンドに送信します。しかし、Cantセットヘッダーの直後に、設定された後、ヘッダーが与えられます。これは、私が "viewCartTable"のIDを見つけたら、私はAjaxリクエストを送信しているからです。そのため、Ajaxリクエストをトリガーしてサーバーとの間でデータをやりとりし、クライアントに返すためのより良い方法が必要です。

このAjaxリクエストで必要なデータを取得する方法はありますか?これまで私の試みでは、負荷と負荷はすべて失敗しました。どんな助けもありがとうございます。ありがとうございました。

第2

データを反復し、表形式で印刷します。だから、サーバー側で私は、この関数の結果取っています:

viewCartPost: function(req, res){ 
     var data = JSON.parse(req.body.data); 
     console.log(data); 
     var keys = Object.keys(data); 
     //console.log(keys); 
     var promises = []; 
     for(var i = 0; i<keys.length; i++){ 
     var productId = keys[i]; 
     promises.push(Product.find({productId: productId}).select({productId : 1, addProductGroupName: 1, productName: 1, productPrice: 1, productDescription: 1, filePath: 1}).exec()); 
     } 
     Promise.all(promises).then(function(results) { 
      // you may have to reorganize results to be exactly what you want 
      // to return to the client 
      var cartTable = viewCartTable(results); 
      res.send("Success^^^"+cartTable); 
     }).catch(function(err){ 
      res.sendStatus(500); 
     }); 
    }, 

をして、この関数からの結果のテーブルを構築している機能に送る:今

function viewCartTable(results){ 
    console.log(results[0]); 
} 

この機能を最初の結果を見ているだけです。 1つの特定の製品のデータセット全体です。そのようになっています。私は結果を呼び出すことができました。このようなテーブルを構築し、私の他のすべてのインスタンスで

[ { _id: 583df3eead025434e61a2172, 
    filePath: '/public/images/df54528a827f99586135956e45f045fe.jpg', 
    addProductGroupName: 'Xbox One', 
    productName: 'Far Cry', 
    productPrice: 78.34, 
    productDescription: 'Its back again. I have never played this game but heard it is pretty good. Wanted to write an extra long description to see if someone really took the time to type such a longer sentence how exactly it would appear on things throughout the application.', 
    productId: 'rJUg4uiGl' } ] 

[0]の結果、特定の商品コードを取得する.productId。ここでは、未定義を返しています。他のすべての試みは、未定義を返す。どのようにしてこのデータセットの各部分を簡単に反復するのか?私はこのサーバーのコードが間違っている:(

+0

どのデータベースを使用していますか?これは私がこの問題を解決するために推奨するコードに影響します。 – jfriend00

+0

MongoDB/Mongoose – Zgbrell

+0

@ jfriend00データの反復処理に問題があります。私は自分の質問にパート2を加えました。どんな助けもありがとうございます。 – Zgbrell

答えて

1

これを把握することはできませんという考えでは、この程度愚かさいますように感じる:。

viewCartPost: function(req, res){ 
     var data = JSON.parse(req.body.data); 
     console.log(data); 
     var keys = Object.keys(data); 
     //console.log(keys); 
     for(var i = 0; i<keys.length; i++){ 
     var productId = keys[i]; 
     Product.find({productId: productId}).select({productId : 1, addProductGroupName: 1, productName: 1, productPrice: 1, productDescription: 1, filePath: 1}).exec(function(err, cartProducts){ 
     if(err){ 
      console.log(err); 
      res.send("error"); 
     }else{ 
      res.send("Success^^^"+cartProducts); 
     } 
     }); 
     console.log(productId); 
     } 
    }, 

あなたはforループ内res.send("Success^^^"+cartProducts);を持っているあなたがいることを意味しつまり、このリクエストに対して複数のレスポンスを送信しようとしているため、表示されているエラーがトリガされます。私はどのコードが最もよく解決するのかを示唆することができる前に、望ましい単一の応答が何であるかを理解しなければならないだろう この問題。このような複数の非同期操作を実行する予定で、それらのすべてが完了した時点を知りたければ、それらを追跡し、すべて完了したときに通知を受け取るコードを記述し、1つだけの応答を送信する必要があります。

これはカウンターとカウンターをインクリメントしてチェックするいくつかのコードで手動で行うことができます。また、非同期操作を追跡するために約束を使用するように切り替えることにより、より管理しやすい方法で行うことができます。Promise.all()すべての非同期操作が行われます。

この機能に複数のキーがある場合、送信する単一の応答は何ですか?私はあまりにも自分自身をマングースを知らないが、私たちは、このように複数の非同期のデータベース操作を調整するためにそれを使用することができますので、マングースのごく最近のバージョンで.exec()は約束を返し


viewCartPost: function(req, res){ 
     var data = JSON.parse(req.body.data); 
     console.log(data); 
     var keys = Object.keys(data); 
     //console.log(keys); 
     var promises = []; 
     for(var i = 0; i<keys.length; i++){ 
     var productId = keys[i]; 
     promises.push(Product.find({productId: productId}).select({productId : 1, addProductGroupName: 1, productName: 1, productPrice: 1, productDescription: 1, filePath: 1}).exec()); 
     } 
     Promise.all(promises).then(function(results) { 
      // you may have to reorganize results to be exactly what you want 
      // to return to the client 
      res.json(results);    
     }).catch(function(err){ 
      console.error("viewCartPost", err); 
      res.sendStatus(500);  
     }); 
    }, 
+0

うーん。アイデアは、サーバー側がループして別のキーを見つけることです。ローカルストレージに追加されたアイテムのproductIdはどれですか。私はそれから、それらの複数のproductIdsを取得し、関連するデータをmongodbのその特定の製品に見つける必要があります。基本的に私はすべての製品とそのデータを表形式にするために私の反応が必要です。データは、{filePath: '/public/images/e6f5cab3de92a9365807cb8301f781b7.jpg'、addProductGroupName: 'Xbox One'、productName: 'スターウォーズ'、productPrice:3000、productDescription: 'description'、productId: 'BJ_7VOiGg'} – Zgbrell

+0

@Zgbrell - 複数の操作を追跡し、すべての結果を収集し、それらがすべて完了したときを知るために、mongooseの約束を使用したソリューションのアイデアを1つ追加しました。 – jfriend00

+0

これは動作しているようです**完璧に**。私は本当に本当にmongoose約束に慣れていませんが、それは間違いなくトリックをしたようです。これは、製品の表を埋めるために必要なすべてのデータを送信しています。 – Zgbrell

関連する問題