Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems trying to return api data without a class

I built an api that returns me the units that I have registered in a DB but when trying to return these are not reviewing

import React, { Component } from 'react';
import axios from 'axios';

const api = {

  units: () => {
    axios.get('http://192.168.0.23/api/public/api/units')
    .then(response => {
      console.log(response);
        return response.data.data
    }).catch((error) => { 
      console.log(error.message)
    });
    return 'Error'
  },

};

export default api;

The response displays the data correctly, the response.data.data if used in a file with a class I can set a state units = [] and with a setState return the units

However I would like to create this file for the api returns, however as I do not use a class so I understand I can not use the state.

Is there any way of without the class returning this data, or keeping in a variable or something of the sort?

Or use setState right here without a class?

I believe that these would be the ways to solve my problem, but if someone else knows otherwise than putting the api call in the same file as the final class may be too.

I tried that way too:

async function getUnits() {   
  return await axios.get('http://192.168.0.23/api/public/api/units');
}

getUnits.then((response) => {
  console.log(response);
    return response.data.data
}).catch((response) => { 
  console.log(response)
});

But the error indicated that getUnits.then is not a function

Even with a normal function did not work:

function units() {
  axios.get('http://192.168.0.23/api/public/api/units')
  .then(response => {
    console.log(response);
      return response.data.data
  }).catch((error) => { 
    console.log(error.message)
  });
  return 'Error'
};
like image 726
Magas Avatar asked Dec 11 '17 16:12

Magas


2 Answers

Use the following code, It will help you.

Normally we would just load the data and then render our app. But React expects some initial state for all that data and needs to update itself once that AJAX request is complete. For this reason, you need to store all that data in the app's state.

Here's how that looks:

      import React, { Component } from 'react';
      import { Platform, StyleSheet, Text, View } from 'react-native';
      import axios from 'axios';


      export default class App extends Component { 

        constructor(props) {
          super(props);

          this.state = {units: []};
        }

        componentDidMount() {
          this.getUnits();
        }

        getUnits() {
          axios.get('http://192.168.0.23/api/public/api/units')
          .then(response => {
            this.setState({ units: response.data.data }));
          }).catch((error) => { 
            console.log(error.message)
          });
        }

        render() {
          const unit = this.state.units.map((item, i) => (
            <div>
              <h1>{ item.example }</h1>
            </div>
          ));

          return (
            <View style={{ flexGrow: 1, alignItems: 'center', justifyContent: 'center' }}>
              <Text>Units: {unit}</Text>
            </View>
          );
        }
      }

And If you want subcomponents to pass that data down to. Here's what that looks like:

          const unit = this.state.units.map((item, i) => (
            <div>
              <h1>{ item.example }</h1>
             <Test unitData={item} />
            </div>
          ));

In different Test component

        class Test extends Component { //use the data in a class component

          constructor(props) {
            super(props);
          }

          render() {
            const unit = this.props.unitData

            return (
              <div className="test">
               <h1>{unit.example}</h1>
              </div>
            );
          }
        }

Please check example to here, which will help you to resolve your issue.

Examples:

  1. react-native-redux-example
  2. basic-react-native-redux-example

Hope this will help you!!

like image 102
Santosh Shinde Avatar answered Nov 12 '22 06:11

Santosh Shinde


I encountered this issue of async callback in my initial days of programming with javascript, where I found it very difficult to pass results between the files using pure functions. There is something I can suggest you, that you can use anywhere with async programming in javascript and has nothing to do with react.js

import React, { Component } from 'react';
import axios from 'axios';

const api = {

  units: (callback) => {
    axios.get('http://192.168.0.23/api/public/api/units')
    .then(response => {
      console.log(response);
        callback(response.data.data);
    }).catch((error) => { 
      console.log(error.message)
    });
    return 'Error'
  },

};

export default api;

And inside your App component:

import React, { Component } from 'react';
import { Platform, StyleSheet, Text, View } from 'react-native';

import api from './units';

export default class App extends Component { 
  constructor(props) {
    super(props);

    this.state = {
      units: [],
    };
  }
  //Always do async tasks(side effects) in componentDidMount, I will provide you a link to know Do's and Dont's with lifecycle hooks.

  componentDidMount() {
    if(this.state.units.length === 0){
      api.units((data) => this.setState({units: data}));
    }
  }

  render() {
    return (
      <View style={{ flexGrow: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Units: {this.state.units}</Text>
      </View>
    );
  }
}

This is the way of passing a callback functions around when you deal with async operations in Javascript, as you can not return a evaluated result from an async function, because as soon as the result is still being evaluated your function will return something and get out of the scope, but you can use the callback handler of the async operation to finally update your view according to the evaluated result. I am only handling the success callback, you can pass error callback as well to handle the error case.

like image 34
smishr4 Avatar answered Nov 12 '22 04:11

smishr4