\href{https://nodei.co/npm/through2/}{\texttt{ }}

{\bfseries{A tiny wrapper around Node streams.\+Transform (Streams2/3) to avoid explicit subclassing noise}}

Inspired by \href{https://github.com/dominictarr}{\texttt{ Dominic Tarr}}\textquotesingle{}s \href{https://github.com/dominictarr/through}{\texttt{ through}} in that it\textquotesingle{}s so much easier to make a stream out of a function than it is to set up the prototype chain properly\+: {\ttfamily through(function (chunk) \{ ... \})}.

Note\+: As 2.\+x.\+x this module starts using {\bfseries{Streams3}} instead of Stream2. To continue using a Streams2 version use {\ttfamily npm install through2@0} to fetch the latest version of 0.\+x.\+x. More information about Streams2 vs Streams3 and recommendations see the article {\bfseries{\href{http://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html}{\texttt{ Why I don\textquotesingle{}t use Node\textquotesingle{}s core \textquotesingle{}stream\textquotesingle{} module}}}}.


\begin{DoxyCode}{0}
\DoxyCodeLine{fs.createReadStream('ex.txt')}
\DoxyCodeLine{  .pipe(through2(function (chunk, enc, callback) \{}
\DoxyCodeLine{    for (var i = 0; i < chunk.length; i++)}
\DoxyCodeLine{      if (chunk[i] == 97)}
\DoxyCodeLine{        chunk[i] = 122 // swap 'a' for 'z'}
\DoxyCodeLine{}
\DoxyCodeLine{    this.push(chunk)}
\DoxyCodeLine{}
\DoxyCodeLine{    callback()}
\DoxyCodeLine{   \}))}
\DoxyCodeLine{  .pipe(fs.createWriteStream('out.txt'))}
\DoxyCodeLine{  .on('finish', () => doSomethingSpecial()) }

\end{DoxyCode}


Or object streams\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{var all = []}
\DoxyCodeLine{}
\DoxyCodeLine{fs.createReadStream('data.csv')}
\DoxyCodeLine{  .pipe(csv2())}
\DoxyCodeLine{  .pipe(through2.obj(function (chunk, enc, callback) \{}
\DoxyCodeLine{    var data = \{}
\DoxyCodeLine{        name    : chunk[0]}
\DoxyCodeLine{      , address : chunk[3]}
\DoxyCodeLine{      , phone   : chunk[10]}
\DoxyCodeLine{    \}}
\DoxyCodeLine{    this.push(data)}
\DoxyCodeLine{}
\DoxyCodeLine{    callback()}
\DoxyCodeLine{  \}))}
\DoxyCodeLine{  .on('data', (data) => \{}
\DoxyCodeLine{    all.push(data)}
\DoxyCodeLine{  \})}
\DoxyCodeLine{  .on('end', () => \{}
\DoxyCodeLine{    doSomethingSpecial(all)}
\DoxyCodeLine{  \}) }

\end{DoxyCode}


Note that {\ttfamily through2.\+obj(fn)} is a convenience wrapper around {\ttfamily through2(\{ object\+Mode\+: true \}, fn)}.\hypertarget{md_sfcode_node_modules_through2_README_autotoc_md30382}{}\doxysection{API}\label{md_sfcode_node_modules_through2_README_autotoc_md30382}
{\bfseries{{\ttfamily through2(\mbox{[} options, \mbox{]} \mbox{[} transform\+Function \mbox{]} \mbox{[}, flush\+Function \mbox{]})}}}

Consult the {\bfseries{\href{http://nodejs.org/docs/latest/api/stream.html\#stream_class_stream_transform}{\texttt{ stream.\+Transform}}}} documentation for the exact rules of the {\ttfamily transform\+Function} (i.\+e. {\ttfamily this.\+\_\+transform}) and the optional {\ttfamily flush\+Function} (i.\+e. {\ttfamily this.\+\_\+flush}).\hypertarget{md_sfcode_node_modules_through2_README_autotoc_md30383}{}\doxysubsection{options}\label{md_sfcode_node_modules_through2_README_autotoc_md30383}
The options argument is optional and is passed straight through to {\ttfamily stream.\+Transform}. So you can use {\ttfamily object\+Mode\+:true} if you are processing non-\/binary streams (or just use {\ttfamily through2.\+obj()}).

The {\ttfamily options} argument is first, unlike standard convention, because if I\textquotesingle{}m passing in an anonymous function then I\textquotesingle{}d prefer for the options argument to not get lost at the end of the call\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{fs.createReadStream('/tmp/important.dat')}
\DoxyCodeLine{  .pipe(through2(\{ objectMode: true, allowHalfOpen: false \},}
\DoxyCodeLine{    (chunk, enc, cb) => \{}
\DoxyCodeLine{      cb(null, 'wut?') // note we can use the second argument on the callback}
\DoxyCodeLine{                       // to provide data as an alternative to this.push('wut?')}
\DoxyCodeLine{    \}}
\DoxyCodeLine{  )}
\DoxyCodeLine{  .pipe(fs.createWriteStream('/tmp/wut.txt')) }

\end{DoxyCode}
\hypertarget{md_sfcode_node_modules_through2_README_autotoc_md30384}{}\doxysubsection{transform\+Function}\label{md_sfcode_node_modules_through2_README_autotoc_md30384}
The {\ttfamily transform\+Function} must have the following signature\+: {\ttfamily function (chunk, encoding, callback) \{\}}. A minimal implementation should call the {\ttfamily callback} function to indicate that the transformation is done, even if that transformation means discarding the chunk.

To queue a new chunk, call {\ttfamily this.\+push(chunk)}---this can be called as many times as required before the {\ttfamily callback()} if you have multiple pieces to send on.

Alternatively, you may use {\ttfamily callback(err, chunk)} as shorthand for emitting a single chunk or an error.

If you {\bfseries{do not provide a {\ttfamily transform\+Function}}} then you will get a simple pass-\/through stream.\hypertarget{md_sfcode_node_modules_through2_README_autotoc_md30385}{}\doxysubsection{flush\+Function}\label{md_sfcode_node_modules_through2_README_autotoc_md30385}
The optional {\ttfamily flush\+Function} is provided as the last argument (2nd or 3rd, depending on whether you\textquotesingle{}ve supplied options) is called just prior to the stream ending. Can be used to finish up any processing that may be in progress.


\begin{DoxyCode}{0}
\DoxyCodeLine{fs.createReadStream('/tmp/important.dat')}
\DoxyCodeLine{  .pipe(through2(}
\DoxyCodeLine{    (chunk, enc, cb) => cb(null, chunk), // transform is a noop}
\DoxyCodeLine{    function (cb) \{ // flush function}
\DoxyCodeLine{      this.push('tacking on an extra buffer to the end');}
\DoxyCodeLine{      cb();}
\DoxyCodeLine{    \}}
\DoxyCodeLine{  ))}
\DoxyCodeLine{  .pipe(fs.createWriteStream('/tmp/wut.txt')); }

\end{DoxyCode}


{\bfseries{{\ttfamily through2.\+ctor(\mbox{[} options, \mbox{]} transform\+Function\mbox{[}, flush\+Function \mbox{]})}}}

Instead of returning a {\ttfamily stream.\+Transform} instance, {\ttfamily through2.\+ctor()} returns a {\bfseries{constructor}} for a custom Transform. This is useful when you want to use the same transform logic in multiple instances.


\begin{DoxyCode}{0}
\DoxyCodeLine{var FToC = through2.ctor(\{objectMode: true\}, function (record, encoding, callback) \{}
\DoxyCodeLine{  if (record.temp != null \&\& record.unit == "{}F"{}) \{}
\DoxyCodeLine{    record.temp = ( ( record.temp -\/ 32 ) * 5 ) / 9}
\DoxyCodeLine{    record.unit = "{}C"{}}
\DoxyCodeLine{  \}}
\DoxyCodeLine{  this.push(record)}
\DoxyCodeLine{  callback()}
\DoxyCodeLine{\})}
\DoxyCodeLine{}
\DoxyCodeLine{// Create instances of FToC like so:}
\DoxyCodeLine{var converter = new FToC()}
\DoxyCodeLine{// Or:}
\DoxyCodeLine{var converter = FToC()}
\DoxyCodeLine{// Or specify/override options when you instantiate, if you prefer:}
\DoxyCodeLine{var converter = FToC(\{objectMode: true\}) }

\end{DoxyCode}
\hypertarget{md_sfcode_node_modules_through2_README_autotoc_md30386}{}\doxysection{See Also}\label{md_sfcode_node_modules_through2_README_autotoc_md30386}

\begin{DoxyItemize}
\item \href{https://github.com/brycebaril/through2-map}{\texttt{ through2-\/map}} -\/ Array.\+prototype.\+map analog for streams.
\item \href{https://github.com/brycebaril/through2-filter}{\texttt{ through2-\/filter}} -\/ Array.\+prototype.\+filter analog for streams.
\item \href{https://github.com/brycebaril/through2-reduce}{\texttt{ through2-\/reduce}} -\/ Array.\+prototype.\+reduce analog for streams.
\item \href{https://github.com/brycebaril/through2-spy}{\texttt{ through2-\/spy}} -\/ Wrapper for simple stream.\+Pass\+Through spies.
\item the \href{https://github.com/maxogden/mississippi}{\texttt{ mississippi stream utility collection}} includes {\ttfamily through2} as well as many more useful stream modules similar to this one
\end{DoxyItemize}\hypertarget{md_sfcode_node_modules_through2_README_autotoc_md30387}{}\doxysection{License}\label{md_sfcode_node_modules_through2_README_autotoc_md30387}
{\bfseries{through2}} is Copyright (c) Rod Vagg \href{https://twitter.com/rvagg}{\texttt{ @rvagg}} and additional contributors and licensed under the MIT license. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details. 