Creating a Newsletter Action and Reducer
Welcome back to the course. So now that we have our new newsletter form built, what we need to do is take this form and basically make it so that when we click on our edit button in the newsletter latest component, we need to take it and have it fill up our form with data.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

Now we can't do this yet because we have no way of taking this. We have no way of finding the newsletter because we don't have it in redux yet. The only place we have it is in our newsletter grid, and it's hardcoded in here.

large

So we have to get this data into redux and simulate what we would do if we were fetching real data. And by taking this approach we can easily implement the GET request from our server to get this data pretty quickly, so let's just throw this into a redux action.

Then we'll fetch it so that our grid can use these items, and we'll put them in the archive, and then take the latest one and put it on our dashboard. So that way, once we do that, we can actually have our items in redux.

So that's how we're going to take that approach. What we're going to have to do is build this action right now to fetch these items. There's going to be more than one so I'll show you how to do that.

Let's go into our actions folder and create a new file for our newsletter actions so it's going actions and create a new file called newsletter.js and in here we want to take a similar approach to what we are doing in auth.js because we're going to be performing post requests.

So in this video we're going to get hardcoded data in the next video and to show you how we can get data from the server. All right so let's go ahead and write it out.

newsletter.js

export function fetchNewsletters() {
    return {
        type: SET_NEWSLETTERS,
        payload:
    }
}

Inside of our auth.js we have a request and What happens is we get a response back, then we get our user back from the token and then we put it into the payload and then we send this to our reducers to try to get the user.

We're going to be doing the same exact thing in newsletter except with newsletters we'll get a response back and then we'll attach to the payload the response.data which is going to be all of our items. Now just so you really understand what's going on here. I'm going to make our own response.data.

newsletter.js

export function fetchNewsletters() {

    const response = {
        data: [

        ]
    }

    return {
        type: SET_NEWSLETTERS,
        payload: response.data
    }
}

Obviously this is hard coded but we'll be able to quickly swap it out when we throw in the get request next video. Let's go grab the data we put in newsletterGrid, and let's put it in our data. We have one newsletter in here, so let's just copy this twice and give it different data so we have two newsletters to work with.

newsletter.js

export function fetchNewsletters() {

    const response = {
        data: [
            {
                _id: '115',
                title: 'Happy Holidays Fam',
                body: 'is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum',
                date: new Date(),
                imageUrl: 'http://via.placeholder.com/960x258'
            },
            {
                _id: '935',
                title: 'Second Newsletter',
                body: 'ng industry. Lo yoooooo dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum',
                date: new Date(),
                imageUrl: 'http://via.placeholder.com/960x258'
            }
        ]
    }

    return {
        type: SET_NEWSLETTERS,
        payload: response.data
    }
}

So we'll just return it and dispatch the newsletters so we can actually use them in redux. Let's go ahead and go to reducers and create a new file and call it newsletterReducer.js. This is going to be pretty similar to authReducer.js so we can copy our file and throw in the newsletter reducer, and alter it.

newsletterReducer.js

import {
    SET_NEWSLETTERS
} from '../actions/types';

const INITIAL_STATE = {
    newsletters: []
}

export default function(state = INITIAL_STATE, action) {
    switch (action.type) {
        case SET_NEWSLETTERS:
            const newsletters = action.payload;
            return {
                ...state,
                newsletters
            }
        default: return state;
    }
}

So it's returning here and let's go create our type as we have done it, and then let's go through this entire flow so you understand what's going on in. Let's open up types.js and let's add in our newsletter type.

types.js

export const AUTHENTICATE_USER = 'AUTHENTICATE_USER';

// NEWSLETTER ACTIONS
export const SET_NEWSLETTERS = 'SET_NEWSLETTERS';

And now what we need to do is make sure we're importing this into actions and into our reducer. Then we need to connect our reducer to our store.

So we have our type, now let's go into our newsletter.js. We need to import SET_NEWSLETTERS into it at the top, so we can dispatch this type into our reducer, which imports it so it can recognize it.

newsletter.js

import {
    SET_NEWSLETTERS
} from './types';

Now we should have access to it. Let's go ahead and let's hook up this reducer now to our reducers index.

reducers/index.js

import { combineReducers } from 'redux';

import { reducer as form } from 'redux-form';
import auth from './authReducer';
import newsletters from './newsletterReducer';


const rootReducer = combineReducers({
  form,
  auth,
  newsletters
});

export default rootReducer;

Now we have access to this, so let's just go on the browser and see what that looks like in redux and then let's go through it one more time and then we will end the video and have this all set up for the next video.

So it's open chrome here and I'm going to open up redux DevTools. Now I'm going to log in but it's not really going to do anything because we're not actually making the call. So right now our state doesn't have our newsletters in the redux DevTools, and even if you log in, it still is not going to have it because we're not actually fetching anything.

large

So we're not calling this action here in newsletter. And as a matter of fact we don't even have a hooked up actions/index.js So let's do that.

actions/index.js

import {
    signUp,
    signIn
} from './auth';

import { 
    fetchNewsletters
} from './newsletter';

export {
    signUp,
    signIn,
    fetchNewsletters
};

Okay cool. Now let's go ahead and let's call this so we can actually see it in redux devtools. So go into newsletterGrid.js and let's fetch it in here. Okay so again just hold up if you're confused. It doesn't matter I'm going to explain it once we fetch them and see it and read our stuff too. So just keep doing what I'm doing and trying to understand if you don't just stand by, all right?

We're going to fetch it here because this is our initial setup right on the grid because you'll see in dashboard that newsletter grid is the first component doing anything having anything to do with it. OK. Now ideally what you'd want to do is make your fetch request in the most root component because you want to get the data as soon as possible. So we might refactor it later but to keep things less confusing, I'm going to perform the get request straight in newsletter grid.

newsletterGrid.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../../actions';

import NewsletterBox from './newsletterBox';
import NewsletterArchive from './newsletterArchive';
import NewsletterLatest from './newsletterLatest';
import Button from '../button';

class NewsletterGrid extends Component {

    handleAddNewsletter = () => {
        this.props.history.push('/newsletter/new');
    }

    componentDidMount() {
        this.props.fetchNewsletters();
    }

So it's going in this componentDidMount it is a lifecycle method that is run before render even runs. So the reason we want to put it in here is because we want to fetch it as soon as we can as soon as we open this component. Now let's change the export at the bottom, so that it can access the store.

large

Let's go to Chrome and you'll see that automatically we have our data being brought in through the reducers.

large

So sweet we've just fetched our newsletters from redux and we put it all up. So that's kind of a lot to comprehend and code out here in a short amount of time. So what I'm going to do is end the video and then in the next video we're going to hook up this data into our component. So we're going to hook it up in archives will only see two newsletters.

So what we need to do is basically hook it all up and then that way we can take the ID and then when we click on this we can use this.props to get these newsletters and display the correct one. Okay so kind of a process just to get this all the work. But once it's all hooked up it's super simple.

Let's go ahead and commit our code.

git status
git add .
git commit -m "built fetchnewsletters action and newsletters actions file and reducer and newsletters reducer"
git push origin master

I'll see in the next video where we will actually hook up this data directly to our front-end.

Resources

Code at this stage