Freddy
Freddy

Reputation: 472

TypeError: Invalid attempt to spread non-iterable instance

After compiling to android and downloading via Store I get the error:

"TypeError: Invalid attempt to spread non-iterable instance"

But using "react-native run-android" creates no error message therefor I can't find a good way to debug it.

fetch(url)
  .then(response => response.json())
  .then(response => {
    if (this._mounted) {
      // let dataSource = this.state.articlesDataSource.cloneWithRows(response.data || [])
      //var rowCount = dataSource.getRowCount();
      var rowCount = Object.keys(response.data).length;

      if (refresh == true) {
        prevData = {};
      } else {
        prevData = this.state.articlesData;
      }
      if (propSearch == "" || propSearch == null) {
        newArticlesData = [...prevData, ...response.data];
      } else {
        newArticlesData = response.data;
      }
      if (response.meta.next_page != null) {
        var rowCount = true;
      } else {
        var rowCount = Object.keys(newArticlesData).length;
      }
      if (this._mounted) {
        this.setState({
          isLoading: false,
          //articlesDataSource: this.state.articlesDataSource.cloneWithRows(response.data),
          articlesData: newArticlesData,
          nextPage: response.meta.next_page,
          fetchUrl: url,
          rowCount: rowCount
        });
      }
    }
  })
  .catch(error => {
    this.setState({
      errorFound: true,
      errorMassage: error,
      isLoading: false
    }); 
});

Thanks for any help.

Upvotes: 28

Views: 130300

Answers (5)

Bronson
Bronson

Reputation: 106

I was getting the same error in a React app in iOS 7 even though Babel was configured to transpile any spread operators. Ultimately, it ended up being some odd issue with an import in my node_modules. The error was resolved after deleting my node_modules directory and simply reinstalling via yarn install (or npm install).

Upvotes: 0

Tanzeel Ur Rehman
Tanzeel Ur Rehman

Reputation: 39

this is because you play around with objects but you trying to copy objects in the array

convert this line

newArticlesData = [...prevData, ...response.data];

to

 newArticlesData = {...prevData, ...response.data};

Your problem solved my code for this is

 fetch(url, {
      method: 'GET',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
        'x-sh-auth': userToken || userStoredToken,
      },
    })
      .then(response => response.text())
      .then(async responseText => {
        let responseData = JSON.parse(responseText);
        console.log('responseData HomeWhatsNewUser', responseData);
        if (responseData.code == 200) {
          setpageNumberwhatsnewap(pageNumberwhatsnewapi + 1);
          setiSloding(false);
          setWhatsNewAPiUser({...WhatsNewAPiUser, ...responseData});
          // setWhatsNewAPiUser(responseData);
          // setLoadMoreNewUserApiLink(responseData.load_more_url);
        } else {
          if (responseData.message === 'Your are un authorize') {
            await AsyncStorage.removeItem('@userData');
            await AsyncStorage.removeItem('@userToken');
            props.navigation.navigate('HomeScreen');
          }
          Toast.show({
            text1: responseData.message,
          });
          setiSloding(false);
        }
      })
      .catch(error => {
        setiSloding(false);
        console.log(error, 'error from APi');
      });
  };

Upvotes: 2

Shah Vipul
Shah Vipul

Reputation: 747

const [myObj,setmyObj = useState({1:"one",2:"two",3:"three",4:"four"} )

where tries to

let newMyObj = [...myObj]   // this will give error as we are trying to iterate over obj by using [] , this way can we used when state is array.

Solution

let newMyObj = {...myObj} // this will works perfectly fine.Iteration is possible above way.

Upvotes: 0

Maulik Dhameliya
Maulik Dhameliya

Reputation: 1558

I was getting this crash in release android build only. release ios build and android debug build working perfectly.

After spending a few hours found solutions from the internet.

edit your .babelrc and add following into your plugins

[
      "@babel/plugin-transform-spread",
      {
        "loose": true
      }
    ]

so Here is my .babelrc file

{
  "presets": [
    "module:metro-react-native-babel-preset"
  ],
  "plugins": [
    "syntax-trailing-function-commas",
    "@babel/plugin-transform-flow-strip-types",
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-transform-regenerator",
    "@babel/plugin-transform-async-to-generator",
    "@babel/plugin-transform-runtime",
    [
      "@babel/plugin-transform-spread",
      {
        "loose": true
      }
    ]
  ],
  "sourceMaps": true
}

I hope this answer helps someone and save few hours :)

Upvotes: 15

Drew Reese
Drew Reese

Reputation: 202696

This is because it is a runtime error, not a "compile time" error.

Is there a line number associated with the error? Based on the question being about the spread operator I'll assume it's this line: newArticlesData=[...prevData,...response.data]. I assume your prevData is iterable, but is your response data? Try newArticlesData=[...prevData, response.data]?

Here's an example of invalid spread operator use:

function trySpread(object) {
  let array;
  try {
    array = [...object];
    console.log('No error', array);
  } catch(error) {
    console.log('error', error);
  }
}

// error
trySpread({});
trySpread({foo: 'bar'});
trySpread(4);

// no error
trySpread([]);
trySpread(['foobar']);
trySpread('foobar');

Upvotes: 28

Related Questions