Simple CRM - A line-of-business app example in Meteor 1.3, React and Redux

Hey all,

I’ve spent the last 8 weeks learning JavaScript, Meteor, React and Redux from the ground up in order to evaluate Meteor as a tool for use in our company.

Our bread and butter work is line-of-business apps for SMEs; we write the boring everyday apps that companies use to manage CRM, orders, production etc. To work out how good a fit Meteor is for that type of work I’ve written a little CRM and orders app called Simple CRM that includes all the bits I need on a regular basis, namely:

  • Data entry forms
  • Business logic
  • Validation logic
  • Real-time validation
  • CRUD
  • Relationships and relational integrity
  • Data denormalization

Rather than sit on that code, it occurred to me that it might be useful to other people. Hopefully it’s a good real-world example to look at after getting your head round the Todo apps. It’s the example I really wanted to see, but couldn’t find, so I wrote myself!

It’s still work in progress, there are things I want to add (top of the list are testing and security), but what’s there works (or it should do, so by all means fire in an Issue report on github if it doesn’t).

So, without further ado, the repo is here: GitHub - tomRedox/simpleCRM: A Meteor, React and Redux Line of Business SPA app example

And the demo is here: http://redoxsimplecrm.meteor.com/

Hope it’s useful :slight_smile:

Edit: I should have said from the outset that I’m indebted to @abhiaiyer for his excellent How we Redux series, companion example app and for looking over my code. And also to @SkinnyGeek1010 for the excellent [meteor flux helpers] (GitHub - AdamBrodzinski/meteor-flux-helpers: Meteor package with general flux helpers) and meteor-flux-leaderboard example. There’s a big list of the learning resources I used in the simpleCRM read me. Many thanks chaps.

38 Likes

Great piece of work. Thanks for sharing.

One question. I noticed you did not use the atmosphere package reywood:publish-composite Have you explored this option? And if yes, where there any contra-indications for using it?

1 Like

Can you give me a skeleton of what that data should look like? Just an outline list, I’m not quite following

I just changed my comment that crossed your response on my original comment

. I had posted my comment before realizing you have a page with an order and all it products; when one creates or edits a specific order.

That’s why I changed my suggestion in the question.

Ah sorry yes I see that now. I simply hadn’t heard of that package, I’ll definitely give it a look.

I wanted a specific behaviour in this instance though whereby I was storing the product name in the order line rather than just the foreign key. That was in order to take advantage of the speed of denormalized data, especially for reporting (which is to come in the future).

It was also to test the denormalisation concept for invoices as I don’t like the descriptions on those to change if the stock item description changes (because I want invoice data to be immutable)

I just commented on a similar issue on your github repo. You should definitely check that out. I can provide you with a few pointers if you like.

I also agree with you on denormalizing invoice line items, but you don’t necessarily need that for reporting. You will most definitely end up using aggregations for that.

1 Like

Thanks for repo, could you tell more about tracking minimongo with redux? Which profits it gives?

@tastemeru I was doing it in order to trigger a re-render when there’s a reactive change to the data from the server. That might not be right, it was certainly the bit I was least sure about how to handle when I wrote it.

At the moment it actually serves no purpose in Redux to trigger an action when the minimongo collections update (i.e. I don’t update anything in the store’s state in response to that change), so I could have left that out of Redux altogether and let the react mixin/React Komposer/TrackerReact sort out the UI.

Ultimately though, I want to do write conflict checking so I can warn the user if the record they are editing has been changed while they are doing the edit, at which point I’ll need to know about the server side changes. To handle that I’ll add a record changed property to the state that will be used to control the rendering of a warning message.

1 Like

Thanks for sharing this I can’t wait to take a look under the hood this weekend.

I’m curious to hear your thoughts about the effort to implement to redux. What were the biggest obstacles and did you discover any techniques to make yourself more efficient. My cursory scan of the developergeist seems to suggest that there is a lot of boilerplate code involved.

@npareek I think there are a few stages to redux:

  1. Total confusion at the concept
  2. Going away and learning the basic concepts of pure functions and immutability
  3. Lightbulb moment of understanding the concept
  4. Creeping realisation how much better a solution the single state model is
  5. Trying to actually learn it, which starts well, but then gets very confusing due to how fast the library has changed and so many of the examples having API calls that no longer work
  6. Trying to work out how much of the Meteor stuff to include in Redux - that took a lot of head scratching, there’s definitely no one-size-fits-all solution to that
  7. Getting some real Redux code up and running with Meteor

Looking at the repo I started wiring in Redux a week ago, so I guess stages 5-7 have taken about 5 days.

I would say Redux is conceptually very simple, but it’s still quite hard to learn because it’s not cast in stone how each part of Redux interacts with everything else (UI and data), and Meteor adds another layer of complexity there.

Boilerplate-wise, my codebase got smaller when I added Redux. There is a bit of boilerplate, but really it’s just wiring you would have had elsewhere most of the time, it’s just that it’s more visible in Redux because it’s spread across less places.

I should say though, all of the above is the ramblings of man who has only been doing javascript for a couple of months. There are others with a lot more experience of this.

7 Likes

Redux has become a real pain to setup boilerplate, especially with dev tools that only load/bundle in dev. Add a redux router and things get untenable quickly.

I made this little helper that glues all of these together so that you can setup Redux, Redux-Dev-Tools, Redux-React-Router, and React-Router in about 4 lines of code.

repo:

working example (non-meteor app)

Also worth mentioning, there were some reported issues with it not working as is with Meteor because the div that the router mounts to is not yet in the DOM. I plan on fixing this but it may need to be wrapped in a .startup func to work. The latest version also has a bug where toggling the devTools config doesn’t do anything… this is fixed but not pushed to GH/NPM yet.

2 Likes

@tomRedox Those are very prescient words that can be applied to learning any new technology. I’m also very new to the world of javascript and I’ve become very spoiled by the Meteor magic of tracker, minimongo and blaze.

Given how new Redux is, and that conventions on integrating it with Meteor are still emerging, I would say five days to implement is quite encouraging to hear.

@SkinnyGeek1010 Thanks for the link, I’ll keep it in mind.

3 Likes

A couple of improvements to Simple CRM over the last few days:

@Stan has very kindly written the security code, so you can now log in and out of the app. That will ultimately then be wired into the publications and methods too.

And I’ve added in some basic unit tests based on the testing recommendations from the upcoming Testing chapter of the Meteor Guide.

Those changes are in the repo, but not on the demo site.

1 Like

Excellent work! Nice to dig into the implementation. Thanks for sharing :wink:

1 Like

Thank you so much Tom! Great resource to start learning React/Redux/Meteor1.3! Now I know where to start!

Hey, this is awesome! I guess most of the questions are going to be about how you did certain things, but I was very interested in this:

I’d love to hear more about this experience. What were you using before? What did you find better and worse in this new stack? (Besides the JS fatigue involved in choosing which tools to use, although it seems you arrived at some of the best ones albeit with a few current growing pains).

Hi @gadicc, many thanks. Looking at the repo traffic it’s clear I wasn’t the only one looking for this type of example! I started writing you a lengthy reply, but then it occurred to me that it would probably be more useful as a blog post, I think there are a lot of currently .net developers looking around and saying “Oh right, about that JavaScript thing…”. I’ll stick a link up here when I get it written.

2 Likes

Blog post would be awesome!

You finally got me to commit to it, I’ve been thinking for weeks “I should be writing this experience up” :smiley:

2 Likes

+1 for the Blog… Like to hear how was the experience in general, compared to your initial company goals? Will you be going this way from now on? What will change?