UgoL
UgoL

Reputation: 919

Get the proper json output with javascript map function in Google Tag Manager

I have this json structure datalayer in GTM where I want to get specific json outcome. I´m trying to use the javascript map function with GTM variable for that, but it just return only the whole string with values. Below the initial json structure that I´m fetching:

dataLayer.push({
  ecommerce: {
    currencyCode: "USD",
    purchase: {
      actionField: {
        id: "xxx",
        revenue: xxx,
        tax: 0,
        shipping: xxx,
        coupon: "",
        discountAmount: 0,
        affiliation: "xxx"
      },
      products: [
        {
          id: "1",
          name: "product1",
          price: xxx,
          unitPriceLessTax: xxx,
          unitPriceWithTax: xxx,
          taxRate: 0,
          quantity: 2,
          category: "",
          brand: "",
          dimension10: "xxx"
        },
        {
          id: "2",
          name: "product2",
          price: xxx,
          unitPriceLessTax: xxx,
          unitPriceWithTax: xxx,
          taxRate: 0,
          quantity: 1,
          category: "",
          brand: "",
          dimension10: "xxx",
          variant: "xxx"
        }
      ]
    }
  }
})

As a first starting point I´m trying to retrieve first the product_quantity and the product_name key values using a mapping javascript function:

 function() {
      var products = {{DLV - Product Name}}; // this DLV is just the products array
      return products.map(function(prod) { return prod.quantity; });
    }

function() {
          var products = {{DLV - Product Name}}; // this DLV is just the products array
          return products.map(function(prod) { return prod.name; });
        }

The problem is that I get as result 2,1 and product1,product2.

So when I´m wrapping up like below:

var result = {

lineitems : [{
        quantity : "{{Product Quantity}}",
        productName: "{{Product Name}}",

    }]

} 

I'm getting this outcome below:

{
  "lineitems": [
    {
      "quantity": "1,2"
    },
    {
      "productName": "product1, product2"
    }
  ]
}

How can I fetch each single values to get this expected json structure?

 {
      "lineitems": [
        {
          "productName": "product1",
          "quantity": "2,"
        },
        {
          "productName":"product2",
          "quantity": "1,"
        }
      ]
    }

Update

When I pass the returned object result from the custom variable function to the main GTM tag it shows me in debug mode not the object json result, but something like google_tag_manager[XXX].macro(187).

Not sure why it doesn´t show the data result calculated with the Javascript map function.

Upvotes: 1

Views: 2259

Answers (3)

UserOfStackOverFlow
UserOfStackOverFlow

Reputation: 108

According by the code you've passed, you can filter the only columns you want by the following code:

var a = { ecommerce: {
    currencyCode: "USD",
    purchase: {
      actionField: {
        id: "xxx",
        revenue: "xxx",
        tax: 0,
        shipping: "xxx",
        coupon: "",
        discountAmount: 0,
        affiliation: "xxx"
      },
      products: [
        {
          id: "1",
          name: "product1",
          price: "xxx",
          unitPriceLessTax: "xxx",
          unitPriceWithTax: "xxx",
          taxRate: 0,
          quantity: 2,
          category: "",
          brand: "",
          dimension10: "xxx"
        },
        {
          id: "2",
          name: "product2",
          price: "xxx",
          unitPriceLessTax: "xxx",
          unitPriceWithTax: "xxx",
          taxRate: 0,
          quantity: 1,
          category: "",
          brand: "",
          dimension10: "xxx",
          variant: "xxx"
        }
      ]
    }
  } }

  var result = a.ecommerce.purchase.products.map(({name, quantity}) => ({name, quantity}));

  //You can do an .each here or loop
  result[0].productName = result[0].name;
  delete result[0].name;

  result[1].productName = result[1].name;
  delete result[1].name;

  var output = { lineItems:
      result
  }

  alert("Result:" + JSON.stringify(output));

In edition of the question I've added the columns name changing.

Upvotes: 0

Giulio Bambini
Giulio Bambini

Reputation: 4755

The reason why you're getting google_tag_manager[XXX].macro(187) is because GTM resolves all the variables in the GTM tag upon injection.

i.e. once the element has been added to the end of and the browser is queued up to execute the code within. Until the variables are resolved, they appear as function calls to this .macro() method - it's GTM's internal method that returns the User-Defined Variable values.

First you need to wrap the map function by creating a Custom Variable called your_variable_name as following:

function() {
  var products = {{DLV - Product Name}};
  return products.map(function(_){ return {
    "quantity":_.quantity,
    "productName":_.name }});
}

Now at this point you need to pass this result to the GTM tag as {{ your_variable_name }}.

If you check in Preview mode, GTM has not yet injected the tag - it just shows what the tag code looks like pre-injection.

//In other words this method with the javascript map function will output the expected json once you'll publish the GTM tag

google_tag_manager[XXX].macro(187) =

{
      "lineitems": [
        {
          "productName": "product1",
          "quantity": "2,"
        },
        {
          "productName":"product2",
          "quantity": "1,"
        }
      ]
    }

Publish the GTM tag and you'll see the calculated result

  • if you custom javascript variable returns the proper json object result, then it is working as expected.
  • the debug preview mode in GTM won't show you any json result untill you don't publish it.
  • you can test it out by submitting and publishing the changes in your GTM workspace.
  • check THIS ANSWER which exactly reproduces your case scenario.

Upvotes: 2

micha
micha

Reputation: 1085

By letting your map function callback return multiple keys, like so:

var expectedJson = {"lineitems": products.map(_ => { return {"quantity":_.quantity, "productName":_.name}})}

edit: in JS < ECMASCRIPT_2015, without the arrow function:

var expectedJson = {"lineitems": products.map(function(_){ return {"quantity":_.quantity, "productName":_.name}})}

Upvotes: 1

Related Questions