0

I have the following snippet of JavaScript I am wrestling with:

 window.bvCallback = function (BV) {  BV.pixel.trackTransaction({
   "currency" : "value",
   "orderId" : "@Model.Order.OrderNumber",
   "total" : "@Model.Order.Total",
   "items" : [
    { -->need a foreach here to loop through the collection to make this key/value pairing for each item
     "price" : "value",
     "quantity" : "value",
     "sku" : "value"
    }
   ]  
 });
};

The problem I have is with the "items" : [] line. I have a collection I need to iterate to create the price quantity and SKU values. This snippet will work to iterate the items:

foreach (var item in Model.Order.LineItems) {item.AdjustedUnitPrice item.sku ...};

So my final outcome needs to be as follows:

..."items" : [
{
  "price" : "140",
  "quantity" : "1",
  "sku" : "156278"

},
{
  "price" : "12.69",
  "quantity" : "3",
  "sku" : "908736"
}]...

So I can get the values I need in the LineItems collection, I just can't seem to put the foreach into the key/value pairing above to get when I need.

Jalissa
  • 826
  • 8
  • 12
john
  • 1,273
  • 3
  • 16
  • 41
  • 2
    You could execute the foreach loop to create your collection _then_ assign it to `items`. – Jasen Oct 09 '17 at 19:27
  • Is it inside a cshtml file? – Ali Seyedi Oct 09 '17 at 20:25
  • To expound upon Jasen's comment: `var items = []; run your for loop and push your objects onto items; ...trackTransaction({...items:items,....})` – SethWhite Oct 09 '17 at 20:27
  • Possible duplicate of [Razor MVC Populating Javascript array with Model Array](https://stackoverflow.com/questions/23781034/razor-mvc-populating-javascript-array-with-model-array) – Ali Seyedi Oct 09 '17 at 21:12
  • Yes it is in a cshtml file. When I use the following code: var items = []; foreach (var item in Model.Order.LineItems) { items.push("price" : item.AdjustedUnitPrice ,"quantity" : item.Quantity,"sku" : item.ProductId); } I get an error on the var "; expected". I am lost here. I haven't done JS on razor pages before. – john Oct 09 '17 at 21:21
  • Use `var model = @Html.Raw(Json.Encode(Model))` to serialize your model to a javascript object/array –  Oct 09 '17 at 21:26
  • I got past the error. How would I push the following ("price" : "123" "quantity" : "1" "sku" : "12345") into items so I add the three pieces of information as 1 item, then create a new item with differing data, and so on? – john Oct 09 '17 at 21:37
  • Here is what I got so far. How do I pass in the items array into the bvCallback function? var items = []; @foreach (var item in Model.Order.LineItems) { @:items.push("@item.AdjustedUnitPrice"); @:items.push("@item.Quantity"); @:items.push("@item.ProductId"); } window.bvCallback = function(BV) { BV.pixel.trackTransaction({ "items": [ { @:items } ] }); }; Will this set the final outcome like I need above? – john Oct 09 '17 at 21:47
  • Okay I change my whole approach and this is what I now have. var TransactionData = { orderId: '@Model.Order.SalesOrderNumber.SelfOrDefault().FullOrderNuber', curreny: "USD", total: '@Model.Order.TotalSalesPrice', items: [ { @foreach (var item in Model.Order.LineItems) { sku: item.ProductId, quantity: item.Quantity, price: item.AdjustedUnitPrice } }] } I am now getting an error after the sku:, quantity: and price: – john Oct 09 '17 at 22:19
  • The error is "; expected" – john Oct 09 '17 at 22:20

1 Answers1

0

If at all possible, setup the model in the C# code instead of within the view.

public class Transaction
{
    public decimal Currency { get; set; }
    public int OrderId { get; set; }
    ...
    public List<Item> Items { get; set; }
}

public class Item
{
    public decimal Price { get; set; }
    public int Quantity { get; set; }
    public string Sku { get; set; }
}

public ActionResult Transaction(string id)
{
    var transaction = service.GetTransaction(id);
    return View(transaction);
}

Then your view simply has the helper

@model Transaction

<script>
    var transaction = @Html.Raw(Json.Encode(Model));
    window.bvCallback = function(BV) { BV.pixel.trackTransaction(transaction); };        
</script>

If you still want to build the object with your method, just assign items after you execute a loop.

<script>
window.window.bvCallback = function (BV) {

    var items = [];

    @foreach (var i in Model.Order.LineItems)
    {
        var item = Html.Raw(Json.Encode(new { price = i.AdjustedUnitPrice, ... }));

        <text>
        items.push(@item);
        </text>
    }

    var transaction = {
       "currency" : "value",
       "orderId" : "@Model.Order.OrderNumber",
       "total" : "@Model.Order.Total",
       "items" : [],  // or just assign it here
        ...
    };

    transaction.items = items;

    BV.pixel.trackTransaction(transaction);
};
</script>

Mixing JavaScript and Razor can get ugly quickly. But the first example keeps the mixing to an absolute minimum while in the second example it is difficult to see where Razor ends and JavaScript begins.

Jasen
  • 14,030
  • 3
  • 51
  • 68
  • There is a view already in c#, the problem is I only need specific values from the view. The section option works great. Thanks. – john Oct 10 '17 at 20:27