0

This simple translation function returns value in it's own file but when I tried calling it in other file and catching result it gives undefined

Here is code below I also made it in codesandbox so it's easier to read: https://codesandbox.io/s/cool-dewdney-qq9pu?fontsize=14&hidenavigation=1&theme=dark

App.js

import React from "react";
import "./styles.css";
import translateText from "./translator";
import { render } from "react-dom";
import Button from "@material-ui/core/Button";

const text = "Dog";
const lang = "pl";
class App extends React.Component {
  translationHandle() {
    if (text && lang) {
      console.log(translateText(text, lang)); // gives undefined
      const result = translateText(text, lang);
      console.log(result); // also gives undefined
    }
  }
  render() {
    return (
      <div className="App">
        <h1>Why does it give undefined</h1>
        <Button onClick={this.translationHandle}>Click</Button>
      </div>
    );
  }
}

export default App;

translate.js

const translate = require("yandex-translate")(api_key);

const translateText = (text, lang) => {
  translate.translate(text, { to: lang }, function(err, res) {
    console.log(res.text); // returns value only in this file
    return res.text; // gives undefined
  });
};

export default translateText;

also secondary question: how can I change translateText function so it catches error as well thank you for help

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
ar2r
  • 45
  • 5
  • The "A" in Ajax. You return a value from the callback function, which executes long after `translateText` has returned undefined. Please see [How do I return the response from an aynchronous call](https://stackoverflow.com/q/14220321/438992), which this duplicates. (Even if it's not a remote call, the issue is the same--`translateText` doesn't return anything, so of course it's undefined. – Dave Newton Jan 09 '20 at 13:56

1 Answers1

0

It's because your return is within the yandex translate function. One way to solve this is to pass a callback into translateText.

translationHandle() {
    if (text && lang) {
        translateText(text, lang, function(result) {
            console.log(result);
        });
    }
}

Then within translateText

const translateText = (text, lang, callback) => {
    translate.translate(text, { to: lang }, function(err, res) {
        callback(res.text);
    });
}

To catch whether there is an error you could check the err parameter and return an object with the status of the response such as

const translateText = (text, lang, callback) => {
    translate.translate(text, { to: lang }, function(err, res) {
        if (err === null) {
            callback({
                success: true,
                data: res.text
            });
        } else {
            callback({
                success: false,
                data: err
            });
        }
    });
};

Then handle this in translationHandle:

translationHandle() {
    if (text && lang) {
        translateText(text, lang, function(result) {
            if (result.success) {
                 console.log("SUCCESS ------->", result.data)
            } else {
                console.log("ERROR --------->", result.data);
            }
        });
    }
}

I've added this back into a Sandbox.

P. Brew
  • 734
  • 4
  • 12