I am relatively new to nodejs/typescript/promises so I am not sure of the correct way to chain promises.
I have a a helper class that calls a REST api to fetch the geolocation based on ip. I am not interested in the entire response, only the city field. How do I correctly return a promise that when resolved gets the city field only?
var rest = require("axios");
const ENDPOINT = "http://freegeoip.net/json/";
@Service()
export class GeoIp {
city(ip: string): Promise<any> {
let promise: Promise<any>;
let p = rest.get(ENDPOINT + ip);
p.then((response) => {
promise = Promise.resolve(() => {return response.data["city"]});
}, (error) => {
promise = Promise.reject(() => { return error});
});
return Promise.resolve(p).then((data)=>promise);
}
}
Here is my test code which fails because the received data object is the original REST response object
import chai = require('chai');
import {GeoIp} from "../../server/services/GeoIp";
var assert = chai.assert;
describe("GeoIp service", () => {
let geoIp: GeoIp;
beforeEach("Initialize service", () => {
geoIp = new GeoIp();
});
var IP_VALID = "137.118.222.187";
it(`Check geolocation of ${IP_VALID}`, (done) => {
let promise = geoIp.city(IP_VALID);
promise.then((data) => {
console.log(data);
assert.equal(data, "Traphill");
done();
});
});
});
var rest = require("axios");
const ENDPOINT = "http://freegeoip.net/json/";
@Service()
export class GeoIp {
city(ip: string): Promise<string> {
return rest
.get(ENDPOINT + ip)
.then((response) => response.data.city);
}
}
The then
method always returns another Promise
and makes Promises chain-able like that.
Looks like the type signature should be Promise<string>
as well.
var rest = require("axios");
const ENDPOINT = "http://freegeoip.net/json/";
@Service()
export class GeoIp {
city(ip: string): Promise<any> {
return rest.get(ENDPOINT + ip).then((res) => res.data.city);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With