Answers.Body: <p>It'd probably be easier to assemble the items the way you need them in Twig, and then JSON encode them. Try something like this:</p>
  
  <pre><code>{% set nations = craft.categories.group('country') %}
  {% set countries = [] %}
  {% for country in nations %}
      {% set thisCountry = {
          'country-id' : country.countryCode,
          'url' : country.url
      } %}
      {% set countries = countries|merge([thisCountry]) %}
  {% endfor %}
  
  {% set countryJs %}         
  var countries = {{ countries|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}
  {% endset %}
  
  {% includeJs countryJs %}
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-25T22:57:09.197Z
Answers.Text: The output is almost there.  As above, the URLs output includes extra slashes http:\/\/mysite.dev\/country\/brazil instead of http:/mysite.dev/country/brazil.   Also, do I integrate this back into the larger JS?
Answers.UserDisplayName: Hellyar
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-25T17:13:10.333Z
Answers.LastActivityDate: 2017-07-25T17:13:10.333Z
Answers.UserDisplayName: GTerrill
Answers.Body: <p>There is a much better way to compose a JSON string from Twig templates: the <a href="https://twig.symfony.com/doc/2.x/filters/json_encode.html" rel="nofollow noreferrer"><code>json_encode</code></a> filter.</p>
  
  <p>To build the data array from your array of category models, you need to loop over them and merge to an empty array row by row.
  When you are ready with your Twig array, you pipe it through <code>json_encode</code>. </p>
  
  <pre><code>{% set data = {} %}
  {% for country in craft.categories.group('country') %}
      {% set data = data|merge([{
          'country-id': country.CountryCode,
          'url': country.url,
      }]) %}
  {% endfor %}
  
  &lt;script type="text/javascript"&gt;
      window.countryData = {{ data|json_encode|raw }};
  &lt;/script&gt;
  
  &lt;script src="/js/app.js"&gt;&lt;/script&gt;
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-25T22:57:33.130Z
Answers.Text: The output is almost there.  Like below, the URLs output includes extra slashes http:\/\/mysite.dev\/country\/brazil instead of http:/mysite.dev/country/brazil.   Also, do I integrate this back into the larger JS?
Answers.UserDisplayName: Hellyar
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-26T01:05:35.037Z
Answers.Text: @Hellyar for the backslashes see my answer here: https://craftcms.stackexchange.com/questions/13458/element-api-urlhelper-generates-backwards-slashes-regex
Answers.UserDisplayName: carlcs
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-26T01:15:47.243Z
Answers.Text: @Hellyar in your main JavaScript file app.js, you have access to the data from the windows object. To log it to the console you’d do `console.log(countryData)`. Updated my answer to show where to load the file.
Answers.UserDisplayName: carlcs
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-25T17:16:40.033Z
Answers.LastActivityDate: 2017-07-26T01:11:19.983Z
Answers.LastEditDate: 2017-07-26T01:11:19.983Z
Answers.UserDisplayName: carlcs
Body: <p>I have a map generated in JS.  </p>
  
  <p>I need to set the <code>country-id</code> and <code>url</code> for each country.  Both 'country-id<code>and</code>url<code>are fields in my Craft categories group</code>countries`.  </p>
  
  <pre><code>{
    "country-id": "FR",
    "url": "http://mysite/country/france"
  },
  </code></pre>
  
  <p>I know (basically) how to output to JS for use in my templates.  <a href="https://craftcms.stackexchange.com/questions/17122/how-can-i-pass-a-craft-field-into-a-javascript-function">Here is a link to an earlier question I asked on how to output to JS.</a> This time my question is not how to include JS, but how do I generate a specific output.</p>
  
  <p>How do I incorporate a <code>for loop</code> that produces the desired output for each member of the category <code>country</code>.</p>
  
  <pre><code>{% set nations = craft.categories.group('country') %}
  {for country in nations %}
  {
  "country-id": "{{country.CountryCode}}",
  "url": "{{country.url}}",
  },
  {% endfor %}
  </code></pre>
  
  <p>Part of the problem is how to I get the loop to also output the script brackets, quotes, commas and attributes that surround the data for each country?</p>
  
  <p>UPDATE -- MORE INFO --- This is the full JS that the above is taken.  </p>
  
  <pre><code>&lt;script type="text/javascript"&gt;
  var map = AmCharts.makeChart( "chartdiv", {
    "type": "map",
      "theme": "light",
      "dataProvider": {
      "map": "worldLow",
      "areas": [ 
  
                {
                  "id": "FR",
                  "url": "http://fmysite.dev/country/france"
                },
                {
                  "id": "JP",
                  "url": "http://mysite.dev/country/japan"
                },
                 {
                  "id": "SA",
                  "url": "http://mysite.dev/country/saudi-arabia"
                },
                 {
                  "id": "GB",
                  "url": "http://mysite.dev/country/united-kingdom"
                },
                ]
    },
     "smallMap":{},
    "areasSettings": {
      // color of areas listed
      "color": "#71d1d7",
      // color of area's outline
      "outlineColor": "#4e93aa",
      // Color of area's outline when user rolls-over it.
      "rollOverOutlineColor": "#000",
      // Color of all areas which are in the map svg file, but not listed as areas in DataSet
      "unlistedAreasColor": "#c7ecf4",
      // Color of all areas' outline which are in the map svg file, but not listed as areas in DataSet 
      "unlistedAreasOutlineColor": "#c7ecf4"
    },
  
    "listeners": [ {
      "event": "clickMapObject",
      "method": function( e ) {
        // check if clicked map object contains "ajaxUrl" parameter
        if ( e.mapObject.ajaxUrl !== undefined ) {
          // add "description" if it was empty
          if ( e.mapObject.description === undefined )
            e.mapObject.description = "&lt;div id='mapcontent'&gt;Loading...&lt;/div&gt;";
  
          // delay loading by a bit so that map can finish displaying description box and zoom
          setTimeout( function() {
            $( "#mapcontent" ).load( e.mapObject.ajaxUrl );
          }, 1000 );
        }
      }
    } ]
  
  
  } );
  &lt;/script&gt;
  </code></pre>
  
Tags: <templating><forloop><javascript>
Title: How do you use a for loop to output to JS?
ThreadText: # How do you use a for loop to output to JS?
  
  (Asked by: username_0 on 2017-07-25)
  
  I have a map generated in JS.
  
  I need to set the `country-id` and `url` for each country. Both 'country-id`and`url`are fields in my Craft categories group`countries`.
  
  ```
  {
    "country-id": "FR",
    "url": "http://mysite/country/france"
  },
  
  ```
  
  I know (basically) how to output to JS for use in my templates. [Here is a link to an earlier question I asked on how to output to JS.](https://craftcms.stackexchange.com/questions/17122/how-can-i-pass-a-craft-field-into-a-javascript-function) This time my question is not how to include JS, but how do I generate a specific output.
  
  How do I incorporate a `for loop` that produces the desired output for each member of the category `country`.
  
  ```
  {% set nations = craft.categories.group('country') %}
  {for country in nations %}
  {
  "country-id": "{{country.CountryCode}}",
  "url": "{{country.url}}",
  },
  {% endfor %}
  
  ```
  
  Part of the problem is how to I get the loop to also output the script brackets, quotes, commas and attributes that surround the data for each country?
  
  UPDATE -- MORE INFO --- This is the full JS that the above is taken.
  
  ```
  <script type="text/javascript">
  var map = AmCharts.makeChart( "chartdiv", {
    "type": "map",
      "theme": "light",
      "dataProvider": {
      "map": "worldLow",
      "areas": [ 
  
                {
                  "id": "FR",
                  "url": "http://fmysite.dev/country/france"
                },
                {
                  "id": "JP",
                  "url": "http://mysite.dev/country/japan"
                },
                 {
                  "id": "SA",
                  "url": "http://mysite.dev/country/saudi-arabia"
                },
                 {
                  "id": "GB",
                  "url": "http://mysite.dev/country/united-kingdom"
                },
                ]
    },
     "smallMap":{},
    "areasSettings": {
      // color of areas listed
      "color": "#71d1d7",
      // color of area's outline
      "outlineColor": "#4e93aa",
      // Color of area's outline when user rolls-over it.
      "rollOverOutlineColor": "#000",
      // Color of all areas which are in the map svg file, but not listed as areas in DataSet
      "unlistedAreasColor": "#c7ecf4",
      // Color of all areas' outline which are in the map svg file, but not listed as areas in DataSet 
      "unlistedAreasOutlineColor": "#c7ecf4"
    },
  
    "listeners": [ {
      "event": "clickMapObject",
      "method": function( e ) {
        // check if clicked map object contains "ajaxUrl" parameter
        if ( e.mapObject.ajaxUrl !== undefined ) {
          // add "description" if it was empty
          if ( e.mapObject.description === undefined )
            e.mapObject.description = "<div id='mapcontent'>Loading...</div>";
  
          // delay loading by a bit so that map can finish displaying description box and zoom
          setTimeout( function() {
            $( "#mapcontent" ).load( e.mapObject.ajaxUrl );
          }, 1000 );
        }
      }
    } ]
  
  } );
  </script>
  
  ```
  
  **Tags:** templating, forloop, javascript
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2017-07-25. Score: 2
  
  It'd probably be easier to assemble the items the way you need them in Twig, and then JSON encode them. Try something like this:
  
  ```
  {% set nations = craft.categories.group('country') %}
  {% set countries = [] %}
  {% for country in nations %}
      {% set thisCountry = {
          'country-id' : country.countryCode,
          'url' : country.url
      } %}
      {% set countries = countries|merge([thisCountry]) %}
  {% endfor %}
  
  {% set countryJs %}         
  var countries = {{ countries|json_encode(constant('JSON_PRETTY_PRINT'))|raw }}
  {% endset %}
  
  {% includeJs countryJs %}
  
  ```
  
  > **Comments:**
  > **username_0**: The output is almost there.  As above, the URLs output includes extra slashes http:\/\/mysite.dev\/country\/brazil instead of http:/mysite.dev/country/brazil.   Also, do I integrate this back into the larger JS?  
  
  ---
  
  ### Answer by username_2 on 2017-07-25. Score: 2
  
  There is a much better way to compose a JSON string from Twig templates: the [`json_encode`](https://twig.symfony.com/doc/2.x/filters/json_encode.html) filter.
  
  To build the data array from your array of category models, you need to loop over them and merge to an empty array row by row.
  When you are ready with your Twig array, you pipe it through `json_encode`.
  
  ```
  {% set data = {} %}
  {% for country in craft.categories.group('country') %}
      {% set data = data|merge([{
          'country-id': country.CountryCode,
          'url': country.url,
      }]) %}
  {% endfor %}
  
  <script type="text/javascript">
      window.countryData = {{ data|json_encode|raw }};
  </script>
  
  <script src="/js/app.js"></script>
  
  ```
  
  > **Comments:**
  > **username_0**: The output is almost there.  Like below, the URLs output includes extra slashes http:\/\/mysite.dev\/country\/brazil instead of http:/mysite.dev/country/brazil.   Also, do I integrate this back into the larger JS?  
  > **username_2**: @username_0 for the backslashes see my answer here: https://craftcms.stackexchange.com/questions/13458/element-api-urlhelper-generates-backwards-slashes-regex  
  > **username_2**: @username_0 in your main JavaScript file app.js, you have access to the data from the windows object. To log it to the console you’d do `console.log(countryData)`. Updated my answer to show where to load the file.  
  
  ---
  
  