35
votes

I was trying to convert the following snippet in nodejs to typescript: How do I make Http Request in Nodejs

Here is my TypeScript code:

import * as http from 'http';

export class HttpRequest{
url: string;
private path: string;
private host: string;
private args: Array<Array<string>>;

constructor(url: string, args?: string){
    this.url = url;
    this.processUrl(this.url);
    if(!!args){
        this.processArgs(args);
    }
    this.args = [];
}
private processUrl(url: string): void {
    let tld: number = url.lastIndexOf('.')
    let sep: number = url.indexOf('/', tld);
    this.host = url.slice(0, sep);
    this.path = url.slice(sep+1);
}
private processArgs(args: string): void {
    let sep: number = args.indexOf('&');
    if(sep < 0){
        return ;
    }
    let argpair: string = args.slice(0, sep);
    let apsep: number = argpair.indexOf('=');
    let k: string = argpair.slice(0, apsep);
    let v: string = argpair.slice(apsep+1);
    this.args.push([k,v]);
    this.processArgs(args.slice(sep+1));
}
private preparePath(): string {
    let path: string = `?`;
    this.args.forEach((arg: Array<string>, i: number): void => {
        let k: string = arg[0];
        let v: string = arg[1];
        path += k + '=' + v;
        if(i == this.args.length-1){
            return ;
        }
        path += '&';
    });
    return path;
}
public addArg(key: string, value: string): void {
    try{
        this.args.push([key,value]);
    } catch(err) {
        console.log(err);
    }
}
public addArgs(args: Array<Array<string>>): void {
    args.forEach((arg: Array<string>): void => {
        this.args.push(arg);
    });
}
public get(cb: (res: any) => any): void {
    let opts = {
        'host': this.host,
        'path': `/${this.path}/${this.preparePath()}`
    };
    http.request(opts, (r: http.IncomingMessage): void => {
        let data = '';
        r.on('data', (chunk: string): void => {
            console.log('Got chunk: ' + chunk);
            data += chunk;
        });
        r.on('end', (): void =>{
            console.log('Response has ended');
            console.log(data);
            cb(data);
        });
        r.on('error', (err): void => {
            console.log('Following error occured during request:\n');
            console.log(err);
        })
    }).end();
}
public test(): void {
    console.log(this.preparePath());
    console.log(`/${this.path}/${this.preparePath()}`);
}
}

Here is my test code:

// Test httpRequest

import { HttpRequest } from './httpRequest';

const request = new HttpRequest('www.random.org/integers');
request.addArg('num', '1');
request.addArg('min', '1');
request.addArg('max', '50');
request.addArg('col', '1');
request.addArg('base', '10');
request.addArg('format', 'plain');
request.addArg('rnd', 'new');
request.test();
request.get((res: string): void => {
    console.log('Response received: ' + res);
});

If this works correctly (I checked the link on Firefox and, it returns a plain text random number) I should get a number as a plain text. However, when I console.log() response, I get nothing. What am I doing wrong here?

3
You probably needed at least http:// in front of your url - Evert

3 Answers

35
votes

I would suggest using https://github.com/node-fetch/node-fetch

import fetch from 'node-fetch';

const response = await fetch('https://api.github.com/users/github');
const data = await response.json();

console.log(data);

For POST request:

import fetch from 'node-fetch';

const response = await fetch('https://bin.org/post', {method: 'POST', body: 'a=1'});
const data = await response.json();

console.log(data);
13
votes

Even though request-promise-native probably works just fine, Axios is a way better alternative for use in TypeScript. It comes with its own type definitions and is overall less dependent on other packages. Using it's API is quite like the answer provided by Adrian, however there are a few subtle differences.

const url: string = 'your-url.example';

try {
    const response = await axios.get(yourUrl);
} catch (exception) {
    process.stderr.write(`ERROR received from ${url}: ${exception}\n`);
}

Obviously you can leave out the try/catch statement if you want the exception to be handled by the client.

-15
votes

Try this :

var request = require('request');
request('www.random.org/integers', function (error, response, body) {
    console.log(response.statusCode);
    cb(response.statusCode);
});

Thanks!