1. Developer Tutorials
  2. Fetching Data from APIs

Fetching Data from APIs

In this tutorial, you will learn how to make network requests in MyCustomScreen.js by using fetch, axios or getApi from @src/services.

To do that, follow the example shown below:

// MyCustomScreen.js
 
import React, {useEffect, useState} from "react";
import {View, Text} from "react-native";
import axios from "axios";
import {connect} from "react-redux";
import {getApi} from "@src/services";
 
const MyCustomScreen = props => {
	const [apiResponse, setApiResponse] = useState({});
   
	useEffect(() => {
		const api = getApi(props.config);
		api.customRequest(
			"[UrL]",          // Endpoint suffix or full url. Suffix will be appended to the site url that app uses. Example of a suffix is "wp-json/buddyboss/v1/members". Example of full url would be "https://app-demos.buddyboss.com/learndash/wp-json/buddyboss/v1/members". 
			"[method]",       // get, post, patch, delete etc.
			{},               // JSON, FormData or any other type of payload you want to send in a body of request
			null,             // validation function or null
			{},               // request headers object
			[true or false]   // true - if full url is given, false if you use the suffix for the url. False is default.
		).then(response => setApiResponse(response.data));
	
		/* or using fetch
		fetch("[FULL_URL]", {
			headers: {
				accessToken: props.token
			}
		}).then(response => setApiResponse(response.json()));
		*/
 
		/*or using axios,  
		axios.get("[FULL_URL]", {
			headers: {
				accessToken: props.token
			}
		}).then(response => setApiResponse(response.data));
		*/

 
		// Note: Sending requests to the app's own backend site may
		// require accessToken in header. In such case, we can simply use
		// props.accessToken which is received from the app's redux store in
		// mapStateToProps.
  	}, [])
 
 
	return (
		<View 
			style={{flex: 1, justifyContent: "center", alignItems: "center"}}
		> 
			<Text>{JSON.stringify(apiResponse)}</Text>
		</View>
	);
 
};
 
 
const mapStateToProps = (state) => ({
  config: state.config,  // not needed if axios or fetch is used
  accessToken: state.auth.token,
});
 
export default connect(mapStateToProps)(MyCustomScreen);

Benefit of using customRequest over others is that you don’t have to send access token explicitly to authenticate user, it’s being done for you. With both fetch and axios you have to send a request header called “accessToken” and provide a token value to it. Moreover, you can pass the validation function to customRequest which can validate the response and if null is returned it will be considered as its passed validation, in other cases error string should be returned. 

Some of the BuddyBoss REST API endpoints (especially those for uploading files) require you to send formData instead of JSON in a request body. Here is an example on what that request code could look:

      const form = new FormData();

       form.append("action", "bp_avatar_upload");
      
       form.append("file", {
           uri: path, // path to an uploaded file
           type: "image/jpg",
           name: "image.jpg"
       });

       const api = getApi(props.config);
       api.customRequest(
           `wp-json/buddyboss/v1/members/${userId}/avatar`,
           "post",
           form,
           null,
           {"Content-Type": "multipart/form-data"},
           false
       ).then(response => setApiResponse(response.data));

Advanced

For more advanced scenarios where it is necessary for you to create a reducer and share data across multiple custom screens, you can create a custom reducer and add it in custom_code/index.js using reduxApi.addReducer hook, which will provide you with an updated Redux store containing our custom API response.

 // MyCustomScreen.js
 
import React, {useEffect, useState} from "react";
import {View, Text} from "react-native";
import axios from "axios";
import {connect} from "react-redux";
 
const MyCustomScreen = props => {
   
  useEffect(() => {
     axios
      .get("[URL]")
      .then(response => props.dispatch({
        type: "CUSTOM_ACTION",
        payload: response.data
      }));
  }, [])
 
 
  return (
   <View
     style={{flex: 1, justifyContent: "center", alignItems: "center"}}
   >
     <Text>{JSON.stringify(props.apiResponse)}</Text>
   </View>
 );
 
};
 
const mapStateToProps = (state) => ({
  accessToken: state.auth.token,
  apiResponse: state.customApiResponseReducer.data
});
 
export default connect(mapStateToProps)(MyCustomScreen);

In index.js

import MyCustomScreen from "./MyCustomScreen";
const {RNCustomCode} = NativeModules;
 
export const applyCustomCode = externalCodeSetup => {
    externalCodeSetup.navigationApi.addNavigationRoute(
       "customScreen",
       "MyCustomScreen",
       MyCustomScreen,
       "noAuth" // "Auth" | "noAuth" | "Main" | "All"
    );
 
 
    externalCodeSetup.reduxApi.addReducer(
     "customApiResponseReducer",
     (state = {data: {}}, action) => {
       if (action.type === "CUSTOM_ACTION") {
         return {...state, data: action.payload};
       } else {
         return state;
       }
     }
    );
};

Furthermore, with addMiddleware you can add your own middleware for handling asynchronous redux actions for example “redux-saga” or “redux-thunk”.

Questions?

We're always happy to help with questions you might have! Search our documentation, contact support, or connect with our sales team.