Object promise ошибка

I’m very new to ReactJS.

I have some problem with the return value of async function

when I call

const result = this.getFieldsAPI();

the result value is [object Promise]

I see [object Promise] from console.log(«result : » + result);

getFieldsAPI = async() => {
    let currentChromosome = "";
    switch (this.state.chromosome) {
      case "Autosom":
        currentChromosome = "/getlocusautosomalkit/";
        break;
      case "Y_STRs":
        currentChromosome = "/getlocusykit/";
        break;
      case "X_STRs":
        currentChromosome = "/getlocusxkit/";
        break;
      default:
        currentChromosome = "";
    }
    let result = [];
    await Axios.get(API_URL + currentChromosome + this.state.currentKit).then((Response) => {
      Response.data.map((locus) => {
        result.push(locus);
      });
    })
    return "result";
  }

  // To generate mock Form.Item
  getFields() {
    const count = this.state.expand ? 10 : 6;
    const { getFieldDecorator } = this.props.form;
    const children = [];
    const result = this.getFieldsAPI();
    console.log("result : " + result);
    for (let i = 0; i < 10; i++) {
      children.push(
        <Col span={8} key={i} style={{ display: i < count ? 'block' : 'none' }}>
          <Form.Item label={`Field ${i}`}>
            {getFieldDecorator(`field-${i}`, {
              rules: [{
                required: true,
                message: 'Input something!',
              }],
            })(
              <Input placeholder="placeholder" />
            )}
          </Form.Item>
        </Col>
      );
    }
    return children;
  }

asked Feb 26, 2019 at 17:47

Sunny's user avatar

4

You’re not waiting for the value of result so you just get an unfulfilled promise. If you change

const result = this.getFieldsAPI();

to

const result = await this.getFieldsAPI();

You’ll get what you’re after. You’ll also need to make getFields() async.

answered Feb 26, 2019 at 17:52

imjared's user avatar

imjaredimjared

19.6k4 gold badges49 silver badges72 bronze badges

1

Async functions would always return a Promise. Promises may be resolved or rejected. You can handle promises in the following ways:

  1. Using then :
this.getFieldsAPI.then((value) => {
  // code on success
}, (errorReason) => {
  // code on error
});
  1. Using await:
try { 
  const result = await this.getFieldsAPI();
} catch(errorReason) { 
  // code on error
}

You may choose on what fits you best. I personally prefer option 2, which seems less confusing.

answered Feb 26, 2019 at 17:58

bitsapien's user avatar

bitsapienbitsapien

1,75312 silver badges24 bronze badges

1

To get a valid response you should adjust your code a bit, because currently you’re returning the string «result» and not the array from your promise.

In your getFieldsApi method you can do following:

...
Response = await Axios.get(API_URL + currentChromosome + this.state.currentKit);
return Response.data.map((locus) => locus);

And you would call it like:

const result = await this.getFieldsApi();

answered Feb 26, 2019 at 17:55

Batajus's user avatar

BatajusBatajus

5,8413 gold badges25 silver badges38 bronze badges

2

Published: 17 February, 2022 |

4 mins(s) read
| Tags:

#programming

#javascript

| Series:

initLogs

Table of contents:


Posts from «InitLogs» series:

  • initLogs 1: Swapping Numbers and Reversing Arrays in JavaScript
  • initLogs 2: Sercret Life of Ifs
  • initLogs 3: Learnings From My Experience on How to Learn Programming
  • initLogs 4: Why am I getting [object Promise] when calling async function in JavaScript
  • initLogs5: Why write simple code?


When I learnt about promises and asynchronous coding. The biggest time consumer was when I tried calling an asynchronous function inside a normal function (synchronous code). I was hoping to use the asynchronous function to get the promises which had the values I was looking for. But what I got was [object Promise]. The asynchronous function was working fine. But when I called the async function inside a normal function it would return [object Promise]. So no promises!

A gif where a woman tells a man no promises.

Why?

You are getting [object Promise] as value because you are calling an asynchronous function inside a synchronous code. This means the synchronous code runs line by line giving no room for asynchronous code to wait and give a response (the promise). You have to wrap an asynchronous function around the asynchronous function you are calling to get the desired result.

An image with an input field and a button.

Initial state of the webpage which have an input field and a button

In the below code, we are creating a function which returns a promise. The below callOpenWeather() function uses fetch API to call the OpenWeather api so that we can get a value called feels_like. This feels_like is a numerical value.


//Async function to fetch the weather info
// using OpenWeather API
const callOpenWeather = async (url) => {
	// Try part when successful return of promise
    try {
		// Calls the API url, parses to JSON, returns
		// feels_like value which is in Farenheit for a particular area.
        let callJson = await fetch(url, {mode: 'cors',});
        let loadJson = await callJson.json();
		return loadJson.main.feels_like;
    
	// Catch part if promise returns an error
	} catch(error) {
        return error;
    }
}

Incorrect way: Asynchronous function inside a synchronous code

Now let’s write a function which will interact with the above callOpenWeather(). The below code won’t work. When you need to call callOpenWeather() function which returns a promise, you cannot call it inside a synchronous code as shown below. It will return [object Promise] as response.

// DOM function to get the data from input and
// use checkWeather function to get the data displayed.
const displayWeather = () => {
    
    const submitButton = document.getElementById('button');
    const inputValue = document.getElementById('search');
    const infoBox = document.getElementById('info-box');

    submitButton.addEventListener('click', () => {
        
        infoBox.style.display = 'grid';
        infoBox.innerText = callOpenWeather(`http://api.openweathermap.org/data/2.5/weather?q=${inputValue.value}&APPID=${apiKey}`); // Use an api key of openweather instead of ${apiKey} to make this code work.
        infoBox.style.boxShadow = '0 0 2px 0 #d3d3d3';    

    });
}

displayWeather();

An image with an input field and a button which displays [object Promise] as response.

The function returns [object Promise] instead of returning the expected value.

This is because when infoBox.innerText calls the callOpenWeather() function, the displayWeather() function is still a normal synchronous function. This means the lines are executed line by line and does not wait for the value from callOpenWeather() which is an asynchronous function. To call callOpenWeather() and get the value (a promise), make it asynchronous. You can do this by wrapping callOpenWeather() inside an async function using async/await method as shown below. This will make an api call to OpenWeather API and wait for the result so that the result can be set and displayed in infoBox.innerText.

Correct way: Asynchronous function wrapped with an asynchronous function

We are wrapping an async function with the eventlistener for the click event. This will let callOpenWeather() function to run properly and wait until it returns a response as provided by the Open Weather API. The below solution uses async/await method. You can see the usage of await keyword which waits for a response from the callOpenWeather() function and returns a promise.


// DOM function to get the data from input and
// use checkWeather function to get the data displayed.
const displayWeather = () => {
    
    const submitButton = document.getElementById('button');
    const inputValue = document.getElementById('search');
    const infoBox = document.getElementById('info-box');

    submitButton.addEventListener('click', async () => {
        
        infoBox.style.display = 'grid';
        infoBox.innerText = await callOpenWeather(`http://api.openweathermap.org/data/2.5/weather?q=${inputValue.value}&APPID=${apiKey}`); // Use an api key of openweather instead of ${apiKey} to make this code work.
        infoBox.style.boxShadow = '0 0 2px 0 #d3d3d3'; 

    });
}

displayWeather();

An image with an input field and a button which displays expected value as response.

The function returns the expected numerical value

This is how you could get the value from your asynchronous code when you are stuck with [object Promise] as your output. This is one of those scenarios where if you think about it, it makes total sense. But our synchronous mind could find it tricky.


Found an error? Have feedback on my writing? DM me on Twitter @unsungNovelty.

← New year resolutions can be a useful & necessary first step

Takeaways from 2021 →


I’m very new to ReactJS.

I have some problem with the return value of async function

when I call

const result = this.getFieldsAPI();

the result value is [object Promise]

I see [object Promise] from console.log(«result : » + result);

getFieldsAPI = async() => {
    let currentChromosome = "";
    switch (this.state.chromosome) {
      case "Autosom":
        currentChromosome = "/getlocusautosomalkit/";
        break;
      case "Y_STRs":
        currentChromosome = "/getlocusykit/";
        break;
      case "X_STRs":
        currentChromosome = "/getlocusxkit/";
        break;
      default:
        currentChromosome = "";
    }
    let result = [];
    await Axios.get(API_URL + currentChromosome + this.state.currentKit).then((Response) => {
      Response.data.map((locus) => {
        result.push(locus);
      });
    })
    return "result";
  }

  // To generate mock Form.Item
  getFields() {
    const count = this.state.expand ? 10 : 6;
    const { getFieldDecorator } = this.props.form;
    const children = [];
    const result = this.getFieldsAPI();
    console.log("result : " + result);
    for (let i = 0; i < 10; i++) {
      children.push(
        <Col span={8} key={i} style={{ display: i < count ? 'block' : 'none' }}>
          <Form.Item label={`Field ${i}`}>
            {getFieldDecorator(`field-${i}`, {
              rules: [{
                required: true,
                message: 'Input something!',
              }],
            })(
              <Input placeholder="placeholder" />
            )}
          </Form.Item>
        </Col>
      );
    }
    return children;
  }

asked Feb 26, 2019 at 17:47

Sunny's user avatar

4

You’re not waiting for the value of result so you just get an unfulfilled promise. If you change

const result = this.getFieldsAPI();

to

const result = await this.getFieldsAPI();

You’ll get what you’re after. You’ll also need to make getFields() async.

answered Feb 26, 2019 at 17:52

imjared's user avatar

imjaredimjared

19.6k4 gold badges49 silver badges72 bronze badges

1

Async functions would always return a Promise. Promises may be resolved or rejected. You can handle promises in the following ways:

  1. Using then :
this.getFieldsAPI.then((value) => {
  // code on success
}, (errorReason) => {
  // code on error
});
  1. Using await:
try { 
  const result = await this.getFieldsAPI();
} catch(errorReason) { 
  // code on error
}

You may choose on what fits you best. I personally prefer option 2, which seems less confusing.

answered Feb 26, 2019 at 17:58

bitsapien's user avatar

bitsapienbitsapien

1,75312 silver badges24 bronze badges

1

To get a valid response you should adjust your code a bit, because currently you’re returning the string «result» and not the array from your promise.

In your getFieldsApi method you can do following:

...
Response = await Axios.get(API_URL + currentChromosome + this.state.currentKit);
return Response.data.map((locus) => locus);

And you would call it like:

const result = await this.getFieldsApi();

answered Feb 26, 2019 at 17:55

Batajus's user avatar

BatajusBatajus

5,8413 gold badges25 silver badges38 bronze badges

2

white and brown long coated small dog

Sometimes, we may run into the «Objects are not valid as a React child (found: [object Promise])» Error when developing React apps.

In this article, we’ll look at how to fix the «Objects are not valid as a React child (found: [object Promise])» Error when developing React apps.

Fix the «Objects are not valid as a React child (found: [object Promise])» Error When Developing React Apps

To fix the «Objects are not valid as a React child (found: [object Promise])» Error when developing React apps, we should make sure the states we’re rendering aren’t set to promises.

For instance, we write:

import React, { useEffect, useState } from "react";

export default function App() {
  const [val, setVal] = useState();

  const getAnswer = async () => {
    const res = await fetch("https://yesno.wtf/api");
    const json = await res.json();
    setVal(json.answer);
  };

  useEffect(() => {
    getAnswer();
  }, []);

  return <div>{val}</div>;
}

We create the getAnswer function that gets data from an API with fetch.

Then we call res.json to convert the response data into a JSON object.

We put await before res.json to get the actual data object instead of a promise assigned to json.

Next, we call setVal to set val to the value of json.answer.

Then in the useEffect callback, we call getAnswer to get the data when the component mounts.

We pass in an empty array into useEffect to make sure the useEffect callback only runs when the component mounts.

And finally, we display the value of val in the div.

Conclusion

To fix the «Objects are not valid as a React child (found: [object Promise])» Error when developing React apps, we should make sure the states we’re rendering aren’t set to promises.

Web developer specializing in React, Vue, and front end development.

View Archive

@jcmoore0

I am trying to code split with React lazy and get error:

Element type is invalid. Received a promise that resolves to: [object Promise]. Lazy element type must resolve to a class or function.

import React, { lazy, Suspense } from 'react'
import * as ReactDOM from 'react-dom'

const Foo = React.lazy(() => import('./foo/foo'))

const App = () => {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <Foo />
      </Suspense>
    </div>
  )
}

repo: https://github.com/jcmoore0/react-lazy-fuse/tree/master/src

Is this method supported?
Fusebox V4 is fantastic. Thanks!

@nchanged

@jcmoore0 thanks ;-) I think it clearly states the error.

Received a promise that resolves to: [object Promise]. Lazy element type must resolve to a class or function.

const Foo = React.lazy( async () => (await import('./foo/foo').MyComponent )

or default as you wish.
I am closing this issue since it’s obvious. You can also try react-universal example

anup88born, brunojppb, acidjunk, rolandin, and escurtcheon12 reacted with thumbs up emoji
ignacio-nacho-barbano, 0OZ, alessiogmonti, sarahysh12, shpilez, visma-jussi-heikkinen, saadricklamar, Derp33, Ked00, ellismarte, and 4 more reacted with thumbs down emoji

@nchanged

Actually, from the doc here

React.lazy takes a function that must call a dynamic import(). This must return a Promise which resolves to a module with a default export containing a React component.

It must be a react component, not a function like in your case

@jcmoore0

@nchanged — Thanks so much for the quick reply.
I am still racking my brain to make this work.

https://reactjs.org/docs/code-splitting.html
didn’t use an aysnc/ await pattern

React.lazy takes a function that must call a dynamic import(). This must return a Promise which resolves to a module with a default export containing a React component.

I was assuming lazy resolves the import promise to get the component from the default.

trying something like this:
const Foo = React.lazy( async () => (await import(‘./foo/foo’).default )

doesn’t work since import(‘./foo/foo’) is a promise and must be followed with .then

Maybe I am trying to hard :)

@nchanged

@jcmoore0 did you read my remark about React.Component You are exporting a function.

@jcmoore0

@nchanged — Yes, I saw your comment, thanks! I was confused as it worked in dev build but not in prod build.

Sharing what I found:

dev build
await import(«./foo/foo») yields {default: ()=>{}}

prod build
await import(«./foo/foo») yields {default: Promise(pending)}

In order to make it work in both dev and prod builds, I needed to return conditionally based on the type of the default which seemed inconsistent.

This works in both prod and dev builds:

const Foo = lazy(async () => {
  let obj = await import("./foo/foo")
  return typeof obj.default === 'function'?obj:obj.default
  }
)

const App = () => {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <Foo />
      </Suspense>
    </div>
  )
}

@nchanged

Oh.. (( I was sure it works ) I will take a look

@nchanged

@jcmoore0 I haven’t forgotten about this issue, don’t you worry.

We are very closing to releasing a fuse compiler (basically an alternative to typescript which is 10x faster) Bear with us, it will solve all the issues.

@lamqson

It sound great!. Would you have any update?

@nchanged

@kwhitley

@nchanged Any update on this one? Appear to be getting the same issue myself… really trying to keep us on fusebox (with a move from 3 to 4) instead of heading back to the world of webpack!

@kwhitley

@jcmoore0 solution of wrapping each async import in additional logic before returning works (very nice dude), but man that’s an ugly solution… hoping to be able to ultimately use the standard «React» away, a la:

const MyAsyncComponent = React.lazy(() => import('./path-to-component'))

// and that's it...

This works in both prod and dev builds:

const Foo = lazy(async () => {
  let obj = await import("./foo/foo")
  return typeof obj.default === 'function'?obj:obj.default
  }
)

const App = () => {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <Foo />
      </Suspense>
    </div>
  )
}

@kwhitley

Unless this is addressed in the compiler, I have a generic workaround function in the meantime that mirrors the «React» way:

// util.js
import React from 'react'

export const lazy = (componentImportFn:Function) => React.lazy(async () => {
  let obj = await componentImportFn()
  return typeof obj.default === 'function' ? obj : obj.default
})
import React from 'react'
import { lazy } from './utils'

const MyAsyncComponent = lazy(() => import('./path-to-component'))

Certainly easier than creating wrapping functions for each :)

@nchanged

@kwhitley hey, the latest alpha build should have it fixed. We are using our own custom compiler for ts and js. But the production flow isn’t quite ready. We’re on it. 4.0.0-alpha.266

@Krak86

According to React documentation route-based-code-splitting:

React.lazy currently only supports default exports. If the module you want to import uses named exports, you can create an intermediate module that reexports it as the default. This ensures that tree shaking keeps working and that you don’t pull in unused components.

So you should do the next steps, for not default modules

// ManyComponents.js
export const MyComponent = /* ... */;
export const MyUnusedComponent = /* ... */;
// MyComponent.js
export { MyComponent as default } from "./ManyComponents.js";
// MyApp.js
import React, { lazy } from 'react';
const MyComponent = lazy(() => import("./MyComponent.js"));

For me it helps.

saurabhgupta11, ruofanwei, mauro1855, matiasfessia, patjab, madhurisandbhor, piyushsarin-sib, SamehElalfi, sarahysh12, and escurtcheon12 reacted with thumbs up emoji
matiasfessia, patjab, piyushsarin-sib, and algomachine007 reacted with hooray emoji

@RealAliHafezi

You must export default the foo file component

@gajjardarshithasmukhbhai

@kwhitley hey, the latest alpha build should have it fixed. We are using our own custom compiler for ts and js. But the production flow isn’t quite ready. We’re on it. 4.0.0-alpha.266

in React TS file I am facing this issue.

Понравилась статья? Поделить с друзьями:
  • Object has no attribute python ошибка
  • Obd2 ошибка 1602
  • Object finereader ошибка цб
  • Obd ошибки что это
  • Obd2 как сбросить ошибки на