How I Fixed: uncaught at check call: argument [object Promise] is not a function

Earlier this month I started dabbling with Redux Sagas as an alternative to Redux Thunks.

At the time I was highly skeptical – largely around whether re-writing a significant portion of my JavaScript was good use of my time, given that I had no prior experience with generators, and that conceptually sagas sounded pretty hard.

But I kept hitting issues with Thunks. They just seemed so cumbersome, and error prone. I found writing tests for them to be painful, and adding in the Redux API Middleware made that even more complicated.

Ultimately, switching to Redux Saga has been one of the highlights of my current project. I love it. Every problem I have had so far has been made easier through the use of sagas.

But today I hit on a problem I haven’t seen before:

uncaught at check call: argument [object Promise] is not a function

This is a generic version of the code I am using:

export function *doRequestProfile(action) {

  try {

    yield put({
      type: types.REQUEST__STARTED,
      payload: {
        requestFrom: 'my-saga'
      }
    });

    const profile = yield call(api.fetchProfile(action.payload.accountId));

    yield put({
       type: types.PROFILE__SUCCESSFULLY_RECEIVED,
       payload: {
         profile
       }
    });

  } catch (e) {

    yield put({
      type: types.PROFILE__FAILED_RECEIVING,
      payload: {
        message: e.message,
        statusCode: e.statusCode
      }
    });

  } finally {

    yield put({
      type: types.REQUEST__FINISHED,
      payload: {
        requestFrom: 'my-saga'
      }
    });

  }
}

export function *watchRequestProfile() {
  yield* takeLatest(types.PROFILE__REQUESTED, doRequestProfile);
}

I have highlighted the problematic line.

The issue here is that the error in the browser is fairly cryptic. It took me digging into the source code to figure this one out.

But actually the issue is really simple to fix.

The highlighted line above should be :

const profile = yield call(api.fetchProfile, action.payload.accountId);

I was calling my function myself, and then passing the promise on to the Saga… whoopsie daisy.

How I Fixed: Uncaught ReferenceError: dispatch is not defined

It’s always a fun time when you hit an error, and you google it, and there’s no #1 result for a StackOverflow post, where someone far smarter than I can ever hope to be has already encountered, resolved, and shared their fix with some other unfortunate soul.

You mean I have to engage my brain and think? World, you can be cruel.

Anyway, tonight’s error (or one of them) was this :

Uncaught ReferenceError: dispatch is not defined

It had me stumped for a while. This is a React app – based on a starter project. So, more than likely, this was my goof.

Anyway, I had myself some forethought and had followed the convention of adding PropTypes to the class I am working on.

See if you can spot the mistake:

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { myAction } from '../actions/someOfMyActions';

class MyClass extends Component {

  constructor(){
    super();
  }

  componentDidMount() {
    const { myAction } = this.props;
    dispatch(myAction('a','b'));
  }

  render() {
    // blah
  }

}

function mapStateToProps(state) {
  return {
    appState: state
  };
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators({
      myAction
    }, dispatch)
  };
}

MyClass.propTypes = {
  appState: PropTypes.object,
  loading : PropTypes.bool,
  items : PropTypes.array
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(MyClass);

Given that apparently, dispatch is not defined, I figured I would add it to the propTypes and see what kind of thing either was, or was not being passed in.

MyClass.propTypes = {
  appState: PropTypes.object,
  dispatch: PropTypes.function,
  loading : PropTypes.bool,
  items : PropTypes.array
};

That led to a new error. Which is good and bad.

Func, Not Function

It means what I did had some noticeable impact, but not the kind of impact that implies it’s resolved:

Warning: Failed prop type: MyClass: prop type `dispatch` is invalid; it must be a function, usually from React.PropTypes.
    in MyClass (created by Connect(MyClass))
    in Connect(MyClass)
    in Provider

Weird.

Looking back over the propTypes I suddenly remembered, it’s not function, it’s func. This caught me out last time.

The error could be nicer I guess.

MyClass.propTypes = {
  appState: PropTypes.object,
  dispatch: PropTypes.func,
  loading : PropTypes.bool,
  products : PropTypes.array
};

Updated, saved, and thanks to hot reloading, that error had gone before I’d tabbed back to my browser.

Cool.

But the problem wasn’t yet resolved. Actually, at this point I’d essentially made little progress in solving the problem.

I had confirmed dispatch was a function though:

Uncaught ReferenceError: dispatch is not defined;

Looking at the problem code again:

  componentDidMount() {
    const { myAction } = this.props;
    dispatch(myAction('a','b'));
  }

At this point I knew this was my boob for sure, and likely the error was staring me right in the face.

So, I did what any code goon would do, and I stuck in a console.log to figure out what the heck was on the props . In a second, you will see why this should have been obvious:

  componentDidMount() {
    const { myAction } = this.props;
    console.log('props', this.props);
    dispatch(myAction('a','b'));
  }

Which output a bunch of stuff which is quite hard to copy / paste in.

Anyway, it turned out on the props  was actions, which just so happened to contain the output from the function I had already declared:

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators({
      myAction
    }, dispatch)
  };
}

doh!

RTFM Chris.

So I could update the call to:

  componentDidMount() {
    const { myAction } = this.props.actions;
    myAction('a','b');
  }

And what-do-you-know?! It worked!

Obvious, in hindsight.

By the way, I appreciate to any season React devs that this is likely a big “durrrr” moment.

Hopefully it saves someone a headache somewhere down the line.

Why I Find JavaScript’s ES6 Destructuring So Fascinating

I spend a lot of time in PHP land.

PHP is a very useful and competent language, but I feel it’s fair to say it lacks somewhat in syntactical grace.

JavaScript’s ES6 on the other hand, is very elegant (to my eyes). This is a snippet from a React tutorial I have been following recently.

  const {
    isFetching,
    lastUpdated,
    items: posts
    } = postsBySubreddit[selectedSubreddit] || {
    isFetching: true,
    items: []
  };

There’s so much going on here.

As a recent migrant to ES6, I find this as intriguing as I do confusing.

The primary concept at work here is ES6 Destructuring. This is a really interesting technique to pull multiple pieces of data from arrays or objects in one go.

I found the concept initially confusing. I read this as a const  that is an object but has no variable name? Not quite.

It’s somewhat easier to understand this statement if we break it down one step further:

  const {
    isFetching,
    lastUpdated,
    items: posts
    } = postsBySubreddit[selectedSubreddit];

I still feel this is complicated for someone, like me, who is new to Destructuring.

Let’s take an even simpler example:

const {a} = {a: 1, b: 2};

This looks a bit easier, a bit more understandable, I feel.

Here we have a regular JavaScript object: {a: 1, b: 2}

We want to create ourselves a constant containing the value of a from this object. A test might illustrate this a little better than words:

it('is possible to grab "a" from our object', () => {
  const ourObject = {a: 1, b: 2};
  let a = ourObject.a; 
  assert.equal(a, 1);
});

Destructuring gives us a short hand notation for this same concept:

it('is possible to grab "a" from our object in a more concise way', () => {
  const {a} = {a: 1, b: 2};
  assert.equal(a, 1);
});

By using the same key name inside the {} ‘s as that which exists on the object, ES6 will go ahead and create us a constant, called a with the value of 1. It essentially pulls out the value from the object and creates a variable / constant for us. Two steps, combined into one. This is one of those things I have immediately started to miss the most when working in PHP.

But what if we don’t want the new constant to be called a, but we do want it to still contain the value of a. Of course, ES6 has you covered here too:

it('is possible to rename "a"', () => {
  const {a: somethingElse} = {a: 1, b: 2};
  assert.equal(somethingElse, 1);
});

Seems a little back to front, but it does make sense. Pull out a as we’ve already covered, and re-name it to somethingElse.

You can see this in action in the React tutorial snippet:

  const {
    isFetching,
    lastUpdated,
    items: posts
    } = postsBySubreddit[selectedSubreddit];

Here, items exists in the original data, and whilst we do want to use the value of items, we want to use a different reference for it – posts.

There are other things we could do with destructuring assignment, it really is quite an awesome concept.

Now we know about these two concepts, let’s take another look at the example:

  const {
    isFetching,
    lastUpdated,
    items: posts
    } = postsBySubreddit[selectedSubreddit];

So we can see both of the above (pulling out by name, and pull-out-and-rename) happening in one statement here.

I found the postsBySubreddit name really confused me. If you can, disregard the name, and simply think of it as an object:

someObject[dynamicKey]

Then for me, it becomes a little easier to reason about:

  it('is possible to use a dynamic key', () => {
    
    let dynamicKey = 'key2';

    const someObject = {
      key1: 'a',
      key2: 'b',
      key3: 'c'
    };
    
    assert.equal(someObject[dynamicKey], 'b');
  });

postsBySubreddit is simply an object with potentially multiple keys.Each key will be the name of a subreddit: ‘php’, ‘reactjs’, ‘programming’ and so on.

We aren’t hard-coding the value of the key we need. We are instead asking for a key using the variable named selectedSubreddit, or dynamicKey in my example.

Don’t just take my word for this though, do look at the code. Unfortunately, I can’t link directly to the line(s) in question, but a quick ctrl+f on the linked page for ‘postsBySubreddit’ will get you to where you need to be.

selectedSubreddit will be one of these keys / subreddits. And all subreddit data will be an array, called items. But because we know that destructuring can rename a property for us, we can take advantage of this to rename items to posts .

isFetching and lastUpdated are both straightforward (in as much as any of this is straightforward), in that they are keys we want to create constants for.

Phew, that’s a lot happening in one statement.

But, remember, we actually broke this line down even further:

  const {
    isFetching,
    lastUpdated,
    items: posts
    } = postsBySubreddit[selectedSubreddit] 
  || {
    isFetching: true,
    items: []
  };

At this stage, we are really only concerned with the bit we haven’t yet covered, so I’ve reformatted it slightly to make it more obvious.

So we’ve done all this destructuring… OR (||) if we are unable to access postsBySubreddit[selectedSubreddit]  then create two constants:

isFetching: true,
items: []

Which would leave lastUpdated as undefined.

But don’t just take my word for it. Have a play around with this code and get a feel for what it is doing. Destructuring is definitely something you will start using more and more, but it’s initially confusing for sure.

JavaScript is moving fast (although I have heard some say that this is slowing down) and if you’re still finding your feet with PHP (or any other language) then I’d advise not to dig to deeply into ES6 just yet.

I’d argue that the transition to ES6 is going to be so challenging for some developers that we may possibly end up in a Python 2 / 3 situation in JavaScript land in the next few years. Which is why I believe the current form of JavaScript will be around for years to come.

Whichever form of JavaScript you choose to use, take the time to dig into the more functional concepts of JavaScript. It will truly help your programming – including your PHP – skills grow.

Notifications with React and Redux

Update 14/03/2017 – better implementation

After recently completing the excellent Reddit API tutorial from the official Redux documentation, I got to implementing a very similar set up in my own application.

One thing pointed out – but not really covered in the tutorial – is that sometimes (more often than I would like to believe, no doubt), communication between the front end and the back end will break.

Now, this sucks for many reasons. But from a user’s perspective, my reasoning is they won’t be as bothered if a little notification / pop up helpfully pops up and says: “heads up, that didn’t work… try again!”

Ok, so they try again and it doesn’t work again. Bad times. Maybe I need to work on my helpful error messages. Or better yet, fix the damn system.

But, message content and flaky systems aside, I decided I wanted to keep track of my notifications via Redux / the application state.

I figured this would be a solved problem. And it is. Kind of.

I found quite a few libraries that already solve this problem, in one way or another:

  • React Toolbox – Snackbar component
  • Igor Prado’s React Notification System
  • Patrick Burtchaell’s React Notifications

And there were others.

I also found a lot of not-React-ified code:

  • Toastr
  • Growler
  • Alertify JS

There’s probably a ton more. It seems like a common problem, with a variety of solutions.

But none of them were Redux-ready, right out of the box. At least, not that I could see.

Being new to Redux, I found this a little worrying (ack, how to do this myself?!) but also an interesting challenge (ack, with what I know so far, can I even do this myself?)

It’s worth noting that the React Toolbox Snackbar component does everything I need. Only, it has a material design theme to it, which I didn’t want. I also didn’t want to have to start styling it. If material design is your thing, that one is a solution.

Then there’s Alertify JS, which is a lightweight, snazzy little bit of code that nails the alerting / notification requirement perfectly. Only there’s a problem.

Alertify JS is an immediately-invoked function function expression (IIFE), which is cool in so much as it “just works”. But it’s not so cool in that I need to hook this up using Redux and I couldn’t figure out a way to make it work how I wanted.

The situation I have is that I want to dispatch a new action every time I need to display a notification. The action would hit the reducer, which would update the state. The state would flow down into my notification component and render a nice notification.

Alertify did not play well with this. As an IIFE, where could I put the alertify.log(‘some message’); method in a way that makes sense to be powered by props? If anywhere, it made most sense to put the call in the reducer switch statement. But that’s not redux.

So that was enough to have ruled out both React Toolbox, and Alertify JS. Onwards.

It boiled down to either React Notifications, or the React Notification System. Neither are pre-configured for Redux. Both fit the component / props requirement though.

Ultimately, I went with the React Notification System, simply as the styling looked like what I wanted. And I very much dislike doing any styling if I really can avoid it.

Ok, so some code.

import React, { PropTypes } from 'react';
import SomeOtherComponent from '../containers/SomeOtherComponent';
import NotificationContainer from '../containers/Notification';

const App = (props) => {
  return (
      <div className="body">
        <SomeOtherComponent props/>
        <NotificationContainer props/>
      </div>
  );
};

export default App;

First thing, add the Notification container on the top level component.

export const ADD_NOTIFICATION = 'ADD_NOTIFICATION';

The action type / constant that matches this action.

import { ADD_NOTIFICATION } from '../constants/ActionTypes';

export function addNotification(message, level) {
  return {
    type: ADD_NOTIFICATION,
    message,
    level
  };
}

Declaring the add notification action function is really straightforward. Just like any other redux action, a simple function containing a payload of data.

import {
  ADD_NOTIFICATION
} from '../constants/ActionTypes';

export default function notification(state = {}, action) {
  switch (action.type) {
    case ADD_NOTIFICATION:
      return Object.assign({}, state, {
        message: action.message,
        level: action.level
      });

    default:
      console.debug('notification reducer :: hit default', action.type);
      return state;
  }
}

The reducer is also very straightforward. As mentioned, I want a component that receives some props (that can change by way of a redux managed state update), and then display a new notification accordingly.

Also, don’t forget to enable this reducer by adding it to the rootReducer :

import { combineReducers } from 'redux';
import {routerReducer} from 'react-router-redux';
import otherReducer from './otherReducer';
import notification from './notificationReducer';

const rootReducer = combineReducers({
  routing: routerReducer,
  otherReducer,
  notification
});

export default rootReducer;

At this stage, I am not concerned with different types of notifications, or doing anything particularly fancy at all. Just some text, and a level, which is React Notification System’s terminology for success, info, warning, etc.

Notice also, the console.debug  statement on the default switch  case? That’s because of this.

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { addNotification } from '../actions/notificationActions';
import NotificationSystem from 'react-notification-system';

class NotificationContainer extends Component {

  constructor(props) {
    super(props);
  }

  componentDidMount() {
    this.notificationSystem = this.refs.notificationSystem;
  }

  componentWillReceiveProps(newProps) {
    const { message, level } = newProps.notification;
    this.notificationSystem.addNotification({
      message,
      level
    });
  }

  render() {
    return (
      <NotificationSystem ref="notificationSystem" />
    );
  }
}

function mapStateToProps(state) {
  return {
    notification: state.notification
  };
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators({
      addNotification
    }, dispatch)
  };
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(NotificationContainer);

The real hard work of actually rendering a notification is given to React Notification System. I just need a way of adding a new notification whenever this component receives some new props.

Anyway, it all works really nicely so far.

I have a variety of actions that make use of fetch, and I’m doing this (simplified to show the dispatching):

return fetch('https://api.some-site.com/whatever.json', { method: 'POST' })
  .then(res => {
    dispatch(addedSomethingElse(somethingElse, res));
    dispatch(addNotification('happy days', 'success'));
  })
  .catch(err => {
    dispatch(failedAddingSomethingElse(somethingElse, err));
    dispatch(addNotification('it went horribly wrong', 'error'));
  });

I’m incredibly new to ES6, React, Redux, and most other parts of the ecosystem, so:

  • if I used any terminology incorrectly;
  • could improve my practices in any way;
  • or did this all wrong!

Then please do leave a comment and let me know 🙂

 

Learning Redux, Or 4 Days On A Typo

In the evenings as of late, I have been diving head first into a brand new tech stack (for me):

  • React
  • Redux
  • React Router

This doesn’t cover all the related technologies that enable this stack to function (webpack, babel, and a whole load more).

I figured learning React, in a general sense, would be fairly challenging, but ultimately worthwhile. I definitely still feel this way.

It took me a while to get my head around React, but once I had, things started dropping into place.

So, I added Redux to the mix.

I followed the Todo tutorial over at the Redux docs, which went well.

Then I set myself a little challenge. I read through the Async Redux tutorial but decided: rather than simply type out what I saw, this time, I would try and reproduce the functionality, but without referring to the docs. Unless very stuck.

The finished project should be able to fetch a list of posts from a given subreddit, and display them in a list. Then, a drop down box should allow changing the subreddit, and also invalidating any locally saved Reddit post titles. Fairly basic in truth.

Things started well. It was a Friday night so beer was involved, but the general functionality for fetching posts, dispatching a request and receive action, and handling those actions seemed in place.

But for some reason, everything kinda died when posts were received.

It’s well worth pointing out, at this point, how useful the Redux Logger middleware can be for getting a feel for just what the heck is happening in your application as the state changes.

However, even with Redux Logger, I still couldn’t figure out what was going wrong. The posts were definitely being requested. The response was being received, and the array containing the posts was populated.

But the next state just would not contain the array posts.

I’m somewhat ashamed to say it took essentially 4 days to spot this typo. But it did, and during that time I learned a really useful, if somewhat fundamentally basic bit of debugging advice:

For the love of God, put a console.log() on your switch default statements.

Also, repeat after me: I before E, except after C.

Sad panda.

export const REQUEST_POSTS = 'REQUEST_POSTS'
export const RECEIVE_POSTS = 'RECEIVE_POSTS'

and:

function postsBySubreddit(state = { }, action) {
  switch (action.type) {
    case INVALIDATE_SUBREDDIT:
    case RECEIVE_POSTS:
    case REQUEST_POSTS:
      return Object.assign({}, state, {
        [action.subreddit]: posts(state[action.subreddit], action)
      })
    default:
      console.log('switch on :: postsBySubreddit default', action.type);
      return state
  }
}

Yup. In my reducer I had made a basic typo (fixed above).

Frustratingly, because these were constants, WebStorm wasn’t detecting my fat fingered tomfoolery.

I wanted to share this not because it was insightful in any serious way. Rather, I want to highlight that mistakes are easily made. Learning new things is hard, and whilst something like this will lead you to drink smack your head against the wall, it is ultimately part of the learning process.

I see all too frequently how beginners get easily frustrated, and worst, believe that experienced programmers know exactly what to do for any situation, and never make mistakes. If only 🙂

Anyway, I strongly recommend the Redux tutorials, and pretty much anything else that Dan Abramov puts out there. This guy is super smart, and an amazing teacher. Thank you Dan!