title: Gruntfile.js building file object dynamically
body: <p><strong>Problem</strong>: On the Grunt project's "Configuring Tasks" page, the "Files Object Format" way of specifying files for a task worked, while the "Files Array Format" and, critically, the "Building the file object dynamically" way (see the "dynamic_mappings" section of their listing) did not.</p>
  
  <p><strong>Questions</strong>: why does listing #2 not work? is the dynamic-file-building example on Grunt's page wrong?</p>
  
  <p><strong>Reference</strong>: the Grunt project page at <em><a href="http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically">Configuring Tasks / Building the Files Object Dynamically</a></em>. </p>
  
  <p>At bottom are two listings for a Gruntfile.js. The first one does not work, while the second one does. The only difference between them is in how each specifies the "files" task:</p>
  
  <pre><code>files: [{
    expand: true,
    cwd: 'views/',
    src: ['**/*.jade'],
    dest: 'html/',
    ext: 'html',
  }],
  </code></pre>
  
  <p>... the one that works reads:</p>
  
  <pre><code>files: {
    expand: true,
    cwd: 'views/',
    src: ['**/*.jade'],
    dest: 'html/',
    ext: 'html',
  },
  </code></pre>
  
  <p>The <strong>only</strong> difference lies in the presence/absence of "[" and "]".</p>
  
  <p>The second listing does not work, but does follow the example at Grunt project's page at <em><a href="http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically">Configuring Tasks / Building the Files Object Dynamically</a></em>.</p>
  
  <p><strong>Listing # 1 (does not work)</strong>:
  aborts with "Warning: Object # has no method 'indexOf' Use --force to continue."</p>
  
  <pre><code>module.exports = function(grunt) {
  
      grunt.initConfig({
  
          jade: {
              options: { pretty: true,
                  data: {
                    debug: true,
                    timestamp: "&lt;%= grunt.template.today() %&gt;"
                  }
              },
              files: [{
                expand: true,
                cwd: 'views/',
                src: ['**/*.jade'],
                dest: 'html/',
                ext: 'html',
              }],
          },
  
          watch: {
              html: {
                  files: ['handlers/**/*.js', 'views/**/*.jade', 'app.js'],
                  tasks: ['jade']
              }
          }
      });
  
      grunt.loadNpmTasks('grunt-contrib-jade');
      grunt.loadNpmTasks('grunt-contrib-watch');
  
      grunt.registerTask('default', ['jade', 'watch']);
  
  }
  </code></pre>
  
  <p><strong>Listing # 2 (works)</strong>:</p>
  
  <pre><code>module.exports = function(grunt) {
  
      grunt.initConfig({
  
          jade: {
              options: { pretty: true,
                  data: {
                    debug: true,
                    timestamp: "&lt;%= grunt.template.today() %&gt;"
                  }
              },
              files: {
                expand: true,
                cwd: 'views/',
                src: ['**/*.jade'],
                dest: 'html/',
                ext: 'html',
              },
          },
  
          watch: {
              html: {
                  files: ['handlers/**/*.js', 'views/**/*.jade', 'app.js'],
                  tasks: ['jade']
              }
          }
      });
  
      grunt.loadNpmTasks('grunt-contrib-jade');
      grunt.loadNpmTasks('grunt-contrib-watch');
  
      grunt.registerTask('default', ['jade', 'watch']);
  
  }
  </code></pre>
  
  <ul>
  <li>"lucky" = spent the weekend reading hundreds of pages about parsing errors, grunt, jade, express, JavaScript, functions and objects... finally deciding that since every reasonable effort had failed, the only thing left to try was the unreasonable.</li>
  </ul>