I'm using the IBM Watson Tone Analyser API with Express.js and React. I have this code which sends some test to the Watson API:
// tone-analyser.js class ToneAnalysis { constructor() { const params = { username: process.env.USERNAME, password: process.env.PASSWORD, version_date: '2018-01-31' } this.Analyzer = new ToneAnalyzerV3(params); } ToneAnalyser(input) { let tones = this.Analyzer.tone(input, (err, tone) => { if (err) console.log(err.message) let voiceTone = tone.document_tone.tones[0].tone_id; console.log(voiceTone) // Logs the right value on Node.js console return voiceTone; }); return tones; } } module.exports = ToneAnalysis;
I then use this on my Express backend like so:
// server.js const ToneAnalysis = require('./api/tone-analyser'); const app = express(); const input = { tone_input: 'I am happy', content_type: 'text/plain' } app.get('/api/tone', (req, res) => { let tone = new ToneAnalysis().ToneAnalyser(input); return res.send({ tone: tone }); });
And I make an API call from React here:
// App.js componentDidMount() { this.callApi() .then(res => { console.log(res.tone); // Logs the wrong value on Chrome console }) .catch(err => console.log(err)); } callApi = async () => { const response = await fetch('/api/tone'); const body = await response.json(); if (response.status !== 200) throw new Error(body.message); console.log(body); return body; };
I expect the value of res.tone
to be a string
showing the tone gotten from the tone analysis function (new ToneAnalysis().ToneAnalyser(input);
). Instead, I get
{ uri: {...},method: "POST", headers: {...}} headers: {...}, uri: {...}, __proto__: Object }
I think this happens because the res.send(...)
runs before tone
has a value from the API. My question is, how do I make res.send(...)
run only after tone
has a value?
I tried wrapping the callback function in this.Analyzer.tone(input, [callback])
in an async/await
block, but that did not fix the issue. Any ideas on how to fix this will be highly appreciated. Thanks!
If the call to
let tone = new ToneAnalysis().ToneAnalyser(input);
returns a promise then you could do something like
tone.then(res.send.bind(res))