Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailem Node/Express.js, získanie return hodnoty z funkcie v inom module

Dobrý deň,

vyrábam prekladač v Node.js, na preklad využívam cloud API, ktoré sa volá cez funkciu, ktorá robí axios post request. Táto funkcia aj preklad fungujú bez problémov. Preklad, teda Response, chcem uložiť do vlastnej premennej (let x), vrátiť túto premennú (return x), a v hlavnom module server.js jej hodnotu nejako odchytiť a odoslať ako JSON (res.json(x)), aby som z tým vedel dalej pracovať na views/index.ejs. Problém je, že preklad zbehne v pohode (viem to podla toho, že som skusal vypísať console.log(res)), no v server.js po odoslaní POST requestu (zatial iba v aplikacií POSTMAN) vypíše x ako undefined.
Môže mi niekto poradiť ako by som to mohol upraviť aby to robilo to, čo som napísal. Pre lepšie pochopenie a štruktúru apky, kt. vyrábam som nahral aj obrazky priamo z editora. A pre lepšie info, ked robim ten request, server na localhoste je samozrejme zapnutý, aj index.ejs sa vyrenderuje. Len to x je furt undefined.

P.S. viem, že by sa to dalo urobiť jednoducho na front-ende v js, ale chcem ten axios robit na backende, lebo v budúcnosti sa module translator.js má rozširovať o dalsie funkcie, validovať dáta a aj zapisovať na databázu.

v programovaní som začiatočník, takže ak robím nejakú smiešnu chybu... nesmejte sa mi. :-)

OS: Windows 10 Home
editor: VSCode

Předmět Autor Datum
Musíš počkat až dostaneš odpověď od serveru. Teď tu hodnotu vracíš okamžitě, bez čekání. Takže použi…
Wikan 06.12.2020 15:01
Wikan
zapisal som celu funkciu asynchronne cez async, await, try, catch, no teraz to dava chybu ze x nieje…
no.name 06.12.2020 15:56
no.name
Tu hodnotu teď ale nikde nevracíš. A i kdybys vracel, tak ji nikde nepoužíváš.
Wikan 06.12.2020 16:02
Wikan
v translator.js som pridal pod ten console.log(x) na dalsi riadok return x; stale rovnaka chyba. x n…
no.name 06.12.2020 16:10
no.name
"x" máš deklarované ve funkci translate, takže nikdo jinde není viditelné. app.post('/', (req, res)…
Wikan 06.12.2020 16:20
Wikan
app.post('/', (req, res) => { const x = translate(req.body.query, req.body.to); console.log(x); // v…
no.name 06.12.2020 16:38
no.name
Pravda. Asynchronní volání je potřeba zpropagovat "nahoru". app.post('/', async (req, res) => { con…
Wikan 06.12.2020 16:43
Wikan
Takze x sa konecne vypisuje. Vdaka. Len ono je to cele k nicomu ked to nejde odoslat ako json. app.…
no.name 06.12.2020 17:12
no.name
No a co je teda v tom "x"?
Wikan 06.12.2020 17:18
Wikan
console.log(x.data); [ { detectedLanguage: { language: 'en', score: 1 }, translations: [ [Object] ]…
no.name 06.12.2020 17:30
no.name
Vypisuješ x.data ale vracíš x?
Wikan 06.12.2020 17:33
Wikan
teraz ano, to len pre ukazku, lebo ste chceli vediet co je v "x". Ide normalne vypisat aj console.lo…
no.name 06.12.2020 17:41
no.name
Nemyslim si, ze je to podstatne, ci tam je x alebo x.data. No podstatné je to docela dost. Měl bys…
Wikan 06.12.2020 17:45
Wikan
No ano, funguje vzdy iba x.data a je jedno ci x.data vratim priamo z funkcie, alebo vratim x a vypis…
no.name 06.12.2020 18:18
no.name
Máš to v té chybové hlášce. Ten objekt x obsahuje nějakou kruhovou referenci a proto nejde serializo…
Wikan 06.12.2020 18:21
Wikan
hmm... predsa asi ide... zatial skusam iba cez ten postman, ale da sa naraz vypisat aj data, aj head…
no.name 06.12.2020 18:35
no.name
predsa asi ide Jde to jenom proto, že nevracíš kompletní x. Tím roztrháním jsi nejspíš roztrhnul ně…
Wikan 06.12.2020 18:40
Wikan
Mam este jeden problem, nejde importovat axios do main.js. axios je nainstalovany cez npm v node_mod… poslední
no.name 07.12.2020 17:28
no.name

v translator.js som pridal pod ten console.log(x) na dalsi riadok return x; stale rovnaka chyba. x nieje definovane. Ale preco neni? Ved x je sucastou tej funkcie a pouziva sa v server.js, teda tam sa ma vypisat.

Celu funkciu som exportoval do server.js, takze vsetko co je zname v nej by malo byt aj v server.js, ci?

app.post('/', (req, res) => {
  const x = translate(req.body.query, req.body.to);
  console.log(x); // vypise Promise { <pending> }
  res.json(x); // v postman pride prazdny objekt {}
})

server.js vracia teraz prazdny objekt

tu funkciu v translator.js mam takto:

const translate = async (string, langCode) => {
  try {
    const x = await axios({
      method: "POST",
      url: process.env.API_URL,
      headers: {
        "content-type": "application/json",
        "x-rapidapi-host": process.env.API_HOST,
        "x-rapidapi-key": process.env.API_KEY,
        "accept": "application/json",
        "useQueryString": true
      },
      params: {
        "profanityAction": "NoAction",
        "textType": "plain",
        "to": `${langCode}`,
        "api-version": "3.0"
      },
      data: [{
        "Text": `${string}`
      }]
    });
    return x;
  } catch (err) {
      console.error(err);
  }
}

Takze x sa konecne vypisuje. Vdaka. Len ono je to cele k nicomu ked to nejde odoslat ako json.

app.post('/', async (req, res) => {
  const x = await translate(req.body.query, req.body.to);
  console.log(x); // funguje
  res.json(x); // chyba
})

chyba:

UnhandledPromiseRejectionWarning: TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'ClientRequest'
    |     property 'socket' -> object with constructor 'TLSSocket'
    --- property '_httpMessage' closes the circle...

skusal som to zapisat aj cez try a catch priamo v tom post route, no stale rovnaka chyba

teraz ano, to len pre ukazku, lebo ste chceli vediet co je v "x". Ide normalne vypisat aj console.log(x), len to vypise velky objekt dat z udajmi o requeste. Nemyslim si, ze je to podstatne, ci tam je x alebo x.data.
A ano, funkcia v translator.js vracia iba to "x". A pokial tomu dobre rozumiem... tak to "return x;" v tej funkcii sa moze volat aj "return y;" nie? Za predpokladu, ze zmenim nazov vo funkcii z "x" na "y".

No ano, funguje vzdy iba x.data a je jedno ci x.data vratim priamo z funkcie, alebo vratim x a vypisem res.json(x.data); Proste cele x nejde vypisat a ja by som praveze potreboval dostat cele x to z toho dovodu, ze mne netreba z toho response len prelozeny text ale aj ine udaje, kt. niesu v data, ale napr. v headers, alebo inde (neviem kde). To by som zistil ak by som vratil vsetko v x a pozrel sa co mi treba a co nie.

Napr. to API ktore pouzivam ma obmedzeny pocet requestov, ktory je mozne vykonat (za 1 mesiac/max. 50 000 req.). No a chcel by som pri kazdom requeste mat prehlad o tom kolko este ich mozem tento mesiac urobit...atd.

Preco nejde vypisat "celu obalku"? Lebo do terminalu VSCode praveze zo zaciatku vypisovalo celu obalku bez problemov.
A teraz skusam, ide aj x.headers vypisat, kde vidim ostatne udaje, ale preco nejde cele x to nechapem, furt dava tu istu chybu...

hmm... predsa asi ide... zatial skusam iba cez ten postman, ale da sa naraz vypisat aj data, aj headers aj ostatne... takto:

app.post('/', async (req, res) => {
  const x = await translate(req.body.query, req.body.to);
  res.json({
    statusCode: x.status,
    statusText: x.statusText,
    data: x.data,
    headers: x.headers
  });
})

odskusane a funguje, inac urobil som si ten response normalne na front-ende v js a kde ide do konzole prehliadaca vypisat cely response tak ako pride a nic okrem toho vyssie v nom neni.

Takze pre zatial by mohol byt moj problem vyrieseny. A dakujem za pomoc.

Mam este jeden problem, nejde importovat axios do main.js. axios je nainstalovany cez npm v node_modules/axios

skúsal som vybrat aj ine subory v tej axios zlozke, ktore tam su no nejde ani jeden, a aj import axios from "axios"; som skusal no stale dava v prehliadaci tu istu chybu.

ten axios.get je len na odskusanie ci funguje, inak chcem vykonat post request na tie data co som vratil tiez cez axios na backende.

Zpět do poradny Odpovědět na původní otázku Nahoru