Download a file with TypeScript

This may apparently be a trivial thing to do. Well, it turns out it was not, at least for me. This is why I would like to share my experience with you, it may save someone several hours of fiddling.

As in the past posts, I will be making my HTTP calls via typed-rest-client. This library is again based on the plain NodeJs http.ClientRequest class. This also means that if you do not plan to use this library, you can still follow the method I’m suggesting.

Here is the full example of the code.

Let’s check what I wrote here and why.

Initially, I do create an instance of the HttpClient class and pass in the user agent parameter (any string will do here). Then I do call a get method to fetch an URL. At this point, I’m ready to persist the response so I do create a write stream for a given path. Here you can improve this code, at example by looking for Content-Disposition header and if present get the filename out of it, etc. The choice is yours and my goal was to show you how to handle the streams in TypeScript.
Now the tricky part, where I lost plenty of time. We need to pipe the message as it is a readable stream to our writable stream. But the fact is that we need to wait until the finish event is triggered. This is where you need to wrap this up in the promise and wait for it to complete. In my example, I also look up for the error event and in case I do reject the promise.

Believe it or not, considering my limited experience with JavaScript and TypeScript, I was not waiting for those events and my code refused to work. I lost some time figuring things out and google was of no much help. As I couldn’t find any TypeScript specific examples, I decided, even if seems banal, to share this with you.

Please share your thoughts with me in case you think this can be improved, I would love to learn more about it.

Cheers

2 thoughts on “Download a file with TypeScript

  1. Node JS free version to get file content, can later save as file via
    https://github.com/eligrey/FileSaver.js

    public static GetFileContentAsync(fileName: string, mimeType: SupportedType|”application/json”, callback: (content: string) => void): void
    {
    const xmlHttpRequest = new XMLHttpRequest();

    xmlHttpRequest.onload = () =>
    {
    if(xmlHttpRequest.readyState === 4)
    {
    if(xmlHttpRequest.status === 200)
    {
    callback(xmlHttpRequest.responseText);
    return;
    }
    else
    {
    console.error(“XMLHttpRequest status not okay (not 200)”);
    console.error(ReadyState: ${ReadyState[xmlHttpRequest.readyState]} - StatusCode: ${xmlHttpRequest.status} - ${xmlHttpRequest.statusText});
    return;
    }
    }
    else
    {
    console.error(“XMLHttpRequest ready state not okay (not 4)”);
    console.error(ReadyState: ${ReadyState[xmlHttpRequest.readyState]} - StatusCode: ${xmlHttpRequest.status} - ${xmlHttpRequest.statusText});
    return;
    }
    };

    xmlHttpRequest.open(“GET”, fileName, true);
    xmlHttpRequest.setRequestHeader(“Content-Type”, mimeType);
    xmlHttpRequest.send(null);
    }

    public enum ReadyState
    {
    NotInitialized = 0,
    RequestSetUp = 1,
    RequestSent = 2,
    RequestInProcess = 3,
    RequestComplete = 4
    }

    1. I saw a lot of libraries that can do that, but I didn’t want to bring in a massive library for such a simple task.
      Also, you are again basing functions on callbacks, not really handy with TypeScript, thus I will prefer promises.

Leave a Reply

Your email address will not be published. Required fields are marked *