Mailchimp Email Report Generator Part II
Tags: api, javascript, node
Published: 2020-11-04 02:09:27

In [part I](https://dev.to/lizlaffitte/mailchimp-email-report-generator-part-1-2m6l) I described my plan for a report generator application. The *plan* was to build the API in Rails and the frontend in React. Well, the best laid plans...

Remember my last user story?

> A user will be able to download a formatted Excel file featuring the report data for a specific campaign

My plan, and that user story in particular, relied on using [React-Export-Excel](https://github.com/securedeveloper/react-data-export). I was able to install and use the package to export simple data. However, whenever I tried to use any of the code examples beyond the simple export, I encountered error after error. 

My entire application depended on being able to export and format the data received from Mailchimp. What's a dev to do? We pivot of course!

<div style="width:100%;height:0;padding-bottom:83%;position:relative;"><iframe src="https://giphy.com/embed/UrbnbuU24p1zgyDMUH" width="100%" height="100%" style="position:absolute" frameBorder="0" class="giphy-embed" allowFullScreen></iframe></div><p><a href="https://giphy.com/gifs/Friends-season-5-episode-113-the-one-with-cop-UrbnbuU24p1zgyDMUH">via GIPHY</a></p>

When I was first researching libraries that would assist with the Excel export, a close second to React-Export-Excel was [Excel4Node](https://www.npmjs.com/package/excel4node). Mailchimp also provides an official client library for Node and often uses Express in their API reference guide. Node, Express and MongoDB are on my list of skills to sharpen. So, Node here we come!

Backtracking to my frontend, before my plans for a Rails API crumbled.

I created a basic React app by running the following command:
```
npx create-react-app mcreports
``
I knew that I wanted to use Redux to manage state and React Router Dom for frontend routing. I installed the following dependencies:

```
npm install --save react-redux
npm install --save redux-thunk
npm install --save react-router-dom
```
I started my frontend build in Index.js. I created a Redux store, gave it an empty reducer and configured it with React-Thunk middleware. Thunk extends Redux and changes the way you dispatch actions in your store.

>Redux Thunk middleware allows you to write action creators that return a function instead of an action. 

```
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware, compose} from 'redux'
import thunk from 'redux-thunk'
import rootReducer from './reducers/rootReducer'

const store =createStore(rootReducer, compose(applyMiddleware(thunk)))
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

```
Next comes App.js. Using `componentDidMount()`, I dispatch the fetchCampaigns action (not yet created) to get the campaign data and add it to the store on mount. I use React Router Dom to specify which components should render for which routes.

I use findCampaign to give the Reports component the correct campaign id (by searching through the campaigns data in the store), when users visit the `/routes/:id` route.

```
import React from 'react';
import './App.css';
import Campaigns from './components/Campaigns'
import {Component} from 'react'
import Report from './components/Report'
import {BrowserRouter as Router, Route, Switch} from 'react-router-dom'
import {connect} from 'react-redux'
import {fetchCampaigns} from './actions/campaignActions'


class App extends Component {
  componentDidMount(){
    this.props.fetchCampaigns()
}

  findCampaign = (id) =>{
    return (this.props.campaigns.find(campaign => campaign.id == id))
  }

  render(){
    return (
      <Router>
      <div className="App">
        <h1>MailChimp Reports</h1>
        <Switch>
          <Route exact path='/' render={props => <Campaigns {...props} /> } />
          <Route exact path="/reports/:id" render={props => <Report {...props} campaign={this.findCampaign(props.match.params.id)}/>} />
        </Switch>
      </div>
      </Router>
    );
  }

}
const mapStateToProps = ({campaigns}) => ({campaigns})
export default connect(mapStateToProps, {fetchCampaigns})(App)

```

In part III we'll keep walking step-by-step (or component-by-component) through the React frontend of my email report generator application.