1

I have a gulp task similar to the following. I am trying to loop through and append a string to the page and also concatenate a corresponding file.

gulp.task('loop', function() {

    for(i =0; i < 10; i++) {

        gulp.src('./build/ross/templates/pages/_page_home.liquid')
            .pipe(plugins.insert.append('Loop ' + i))
            // real example has concat here
            .pipe(plugins.addSrc('./src/page/_page' + i + '.liquid'))
            .pipe(plugins.concat('_page_home.liquid'))
            .pipe(gulp.dest('./build/ross/templates/pages/'));

    }

});

Expected output would be something like

Loop 1
// _page1.liquid contents
Loop 2
// _page2.liquid contents
Loop 3
// _page3.liquid contents
and so on...

Actual output appears more like

// Original Page Contents here
Loop 9
// _page9.liquid contents

I did a fs.readFile on the original file in the loop and outputted the data and it is only outputting the original page contents and not the concatenated file or the string I'm trying to append.

I also did a console.log(i) inside and it's showing the proper numbers 1,2,3,4,5,6,7,8,9. I wonder if this has something to do with the gulp.src()

Update: Sometimes it appears that the output contents will actually have parts of the _page#.liquid contents. It is a bit inconsistent.

Is there a better way to do this with gulp or am I just doing something wrong?

Ross
  • 314
  • 1
  • 2
  • 8
  • possible duplicate of [JavaScript closure inside loops – simple practical example](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – hereandnow78 May 05 '15 at 19:21
  • If I `console.log(i)` it will output 0,1,2,3,4,5,6,7,8,9 etc... – Ross May 05 '15 at 19:45
  • inside your gulp-pipes you are asynchronous! your loop itself is NOT asynchronous. put the stuff in your loop inside a function and call that from inside your loop (with `i` as argument), and you will see it will work! – hereandnow78 May 05 '15 at 20:42
  • I am still getting the same issues, how can I tell one stream to finish before doing anything else? – Ross May 05 '15 at 22:09
  • Got it to work using `stream-to-promise` and `bluebird` -- see https://gist.github.com/rdallaire/e84a796a09e2aa189534 – Ross May 05 '15 at 22:40
  • now i got what you wanted to achieve. nice workaround... – hereandnow78 May 06 '15 at 07:04
  • Thanks hereandnow78! – Ross May 06 '15 at 16:31

1 Answers1

1

Got it to work with some help from the people at #gulpjs on freenode irc.

This uses stream-to-promise and bluebird

var s2p = require('stream-to-promise');
var Promise = require('bluebird');

gulp.task('loop2', function() {
    // don't forget your `var`s!
    var buildIt = function(i){
        return gulp.src('./build/ross/templates/pages/_page_home.liquid')
            .pipe(plugins.insert.append('Loop ' + i))
            .pipe(gulp.dest('./build/ross/templates/pages/'))
            .on('end', function(){ console.log(i + ' -- done')});
    }

    var indexes = [];

    for(var i = 0; i < 10; i++) {
        indexes.push(i);
    }

    // // sequence them
    indexes.reduce(function(p, index){
        return p.then(function(){
            return s2p(buildIt(index));
        });
    }, Promise.resolve());

});
Ross
  • 314
  • 1
  • 2
  • 8