App Diary: Day 5

Continuing to build a career re-training app for millennials. #ReactNative #iOS #Android

Here’s the GitHub repo, updating in real time as I code.


Today I was tackling the Profile page and the mechanic of adding courses to a saved “Your courses” list. (See screenshot at left)

I’m really liking modal interfaces for scrolling through options. In the main Courses tab (see center and right screenshots), I implemented a modal component in connection with the category picker.

Left: Profile page with “Your courses” section. Center: Courses screen. Right: Modal after clicking the category picker.

On a mobile device, you don’t want to be scrolling through a huge list of categories in a tiny segmented window; a modal gives more real estate and a single purpose for the screen.

React Native makes this really easy with the native Modal component, and I adapted it into my own custom reusable component called ModalView, which incorporates a “close” button and takes a custom onClose function.

class ModalView extends Component { 
static defaultProps = {
visible: false,
onClose: () => {}
}
...

Since I made it customizable, I decided to use this same ModalView component for the “Add course” functionality. Click “Add” on the Profile screen and the following modal appears:

When you finish typing and click the “Search” button on the Keyboard, you see a loading gif and then the search results (consisting of the Course component I built earlier for the Courses screen).

The Course component takes an Id prop, which I grab from the Udemy API. I put the API call itself into the helper function file, since it won’t be creating an action and going through to Redux state. Instead, it’s a promise-based async function that returns a Promise with the search results object.

export const searchForCourses = (searchTerm) => { 
return new Promise(async (resolve, reject) => {
try {
const url = buildSearchQueryUrl(searchTerm);

let resultsObject = await axios({
method: ‘get’,
url,
auth: {
username: udemyConfig.clientId,
password: udemyConfig.clientSecret
}
});
      const results = resultsObject.data; 
resolve(results);
} catch (error) {
console.log(error.response);
reject(error);
}
});
};

Then the search results are saved to component-level state…

let searchResults = await helpers.searchForCourses(searchTerm);      const courses = searchResults.results;     
let courseIds = [];
courses.map(course => courseIds.push(course.id));
this.setState({        
searchResults: courseIds,
searchResultsLoading: false
});

and can then be displayed in the view.

renderSearchResults() { 
if (this.state.searchResultsLoading) {
return (
<ActivityIndicator size=”large” style={{ marginTop: 50 }} />
);
}
  return ( 
<ListView
contentContainerStyle={styles.listView}
dataSource={this.ds.cloneWithRows(this.state.searchResults)}
renderRow={(rowData) => this.renderRow(rowData) }
/>
);
}

Screenshot below of the result.

Tap “Add” and — thanks to the custom onPress function prop in the Course component…

onPress={() => this.addCourseToSavedCourses(courseId)}

…that course ID gets added to the currentUser object in Redux state, and the modal closes.

addCourseToSavedCourses = (courseId) => {
this.props.addCourseToSavedCourses(courseId);
  this.hideModal(); 
}

(Sorry, Medium isn’t the best format to copy/paste code… the full source is on GitHub)

And there ya have it.

Next up is the Feed screen, where people can post what courses they’re taking and see what other people are up to.