Using Normalizr to organize data in stores — practical guide

Solve the issues with data organizing:  #ReactJS #JavaScript

  • Using Normalizr to organize data in stores — practical guideA React application usually needs some data from the server to be stored locally for immediate use, mainly to be shown on the page.
  • In the response for teachers we get something like this (shape of a server response): [ { students: [ { id, name, studentCourses: [ { studentId, courseId, grande, }, … ], }, … ], courses: [ { id, name, }, … ], }, … ]Here you can read about how to combine data in queries, if you also use Loopback.In this particular case this would spare us two requests, but this is not very useful if we speak about storing on front-end.
  • Secondly, we might need courses inside of a student entity instance, but when we make a query to the server, we don’t include these courses to avoid duplication.To cope with the described issues we can start with Normalizr — a utility that normalizes data with nested objects, just like in our case.
  • If you haven’t used redux-saga in your projects yet, I think this should convince you to do so.The first saga will fetch data:const urls = { teachers: ‘/teachers, students: ‘/students’, courses: ‘/courses’,};export function* fetchModel(model, ids, include) { const url = urls[model]; const where = {id: {inq: ids}}; const filter = {where, include}; const params = {filter}; return yield get({url, params});}The second will store the data:export function* queryModels(modelName, ids, include]) { const singleModelSchema = schema[modelName]; const denormalizedData = yield fetchModel(modelName, ids, include); const normalizedData = normalize(denormalizedData, [singleModelSchema]); const {entities} = normalizedData; yield a reducer will add new pieces of data to the already fetched ones:case ADD_ENTITIES: { const models = action.entities; const newState = cloneDeep(state); return mergeWith(newState, models);}Methods mergeWith and cloneDeep here are from lodash.Having done all that we can query data from server in this manner (selector):export function* fetchTeachers() { yield queryModels(‘teachers’, ids, [ { relation: ‘students’, scope: { include: [‘studentCourses’], } }, { relation: ‘courses’, } ]);}Normalizr uses a normalization schema as described here.Eventually we end up with the state that looks like this: state: { … models: { teachers: {…}, sudents: {…}, courses: {…}, studentCourses: {…}, }, … }This basically is a nice little copy of a part of our database in the store.
  • It is done in queryModels saga and we always know where the fetched data is going to be put.After that we can use it in any page of the app combing it in selectors as required.In our case, if needed, we can get an object for teacher as complicated as this (denormalized data): { students: [ { id, name, studentCourses: […], courses: […], }, … ], courses: [ { id, name, sudents: […], teachers: […], }, … ], }There is also another way.

In one of the projects, we encountered the issues with data organizing. To cope with that we can use Normalizr — a utility that normalizes data with nested objects.
Continue reading “Using Normalizr to organize data in stores — practical guide”

React Fundamentals with Wes Bos Tickets, Fri, Sep 8, 2017 at 9:00 AM

  • This workshop is aimed at understanding the fundamentals of React.
  • Throughout the day, participants will work to build an application by incrementally learning each fundamental concept in React.
  • By taking the time to implement it into an application, participants will get a hands-on approach to understanding why and how React works.
  • Refunds for HackerYou workshops will only be given if we are notified 7 days prior to the event.

Eventbrite – HackerYou presents React Fundamentals with Wes Bos – Friday, September 8, 2017 at HackerYou, Toronto, ON. Find event and ticket information.
Continue reading “React Fundamentals with Wes Bos Tickets, Fri, Sep 8, 2017 at 9:00 AM”

Extracting Logic from React Components

Extracting Logic from #ReactJS Components:  by @Jack_Franklin #Javascript

  • Right now to test formatting of amounts I have to create and mount a React component, but I should be able to just call that function and check the result.
  • Let’s create which will house the function that is currently in our component.
  • To test this, we can replace the body of ’s so that it just calls the new function from our module:

    Notice that I’ve still left the function defined on ; when pulling code apart like this you should do it in small steps; doing it like this decreases the chance of inadvertently breaking the code and also makes it easier to retrace your steps if something does go wrong.

  • Sure, the function is very straightforward for now, but as it grows we can now test it very easily without any need to fire up a React component to do so.
  • By looking through our components and finding standalone functions that we can pull out, we’ve greatly simplified our component whilst increasing our test coverage and clarity of our application greatly.

In the previous screencast we took a React component that was doing too much and refactored it, splitting it into two components that are easier to maintain, use and test. Although I’d recommend watching that video first, you don’t need to have watched it to read this blog post. You can find all the code on GitHub if you’d like to run it locally.
Continue reading “Extracting Logic from React Components”

Using Normalizr to organize data in stores — practical guide

Solve the issues with data organizing:  #ReactJS #JavaScript

  • Using Normalizr to organize data in stores — practical guideA React application usually needs some data from the server to be stored locally for immediate use, mainly to be shown on the page.
  • In the response for teachers we get something like this (shape of a server response): [ { students: [ { id, name, studentCourses: [ { studentId, courseId, grande, }, … ], }, … ], courses: [ { id, name, }, … ], }, … ]Here you can read about how to combine data in queries, if you also use Loopback.In this particular case this would spare us two requests, but this is not very useful if we speak about storing on front-end.
  • Secondly, we might need courses inside of a student entity instance, but when we make a query to the server, we don’t include these courses to avoid duplication.To cope with the described issues we can start with Normalizr — a utility that normalizes data with nested objects, just like in our case.
  • If you haven’t used redux-saga in your projects yet, I think this should convince you to do so.The first saga will fetch data:const urls = { teachers: ‘/teachers, students: ‘/students’, courses: ‘/courses’,};export function* fetchModel(model, ids, include) { const url = urls[model]; const where = {id: {inq: ids}}; const filter = {where, include}; const params = {filter}; return yield get({url, params});}The second will store the data:export function* queryModels(modelName, ids, include]) { const singleModelSchema = schema[modelName]; const denormalizedData = yield fetchModel(modelName, ids, include); const normalizedData = normalize(denormalizedData, [singleModelSchema]); const {entities} = normalizedData; yield a reducer will add new pieces of data to the already fetched ones:case ADD_ENTITIES: { const models = action.entities; const newState = cloneDeep(state); return mergeWith(newState, models);}Methods mergeWith and cloneDeep here are from lodash.Having done all that we can query data from server in this manner (selector):export function* fetchTeachers() { yield queryModels(‘teachers’, ids, [ { relation: ‘students’, scope: { include: [‘studentCourses’], } }, { relation: ‘courses’, } ]);}Normalizr uses a normalization schema as described here.Eventually we end up with the state that looks like this: state: { … models: { teachers: {…}, sudents: {…}, courses: {…}, studentCourses: {…}, }, … }This basically is a nice little copy of a part of our database in the store.
  • It is done in queryModels saga and we always know where the fetched data is going to be put.After that we can use it in any page of the app combing it in selectors as required.In our case, if needed, we can get an object for teacher as complicated as this (denormalized data): { students: [ { id, name, studentCourses: […], courses: […], }, … ], courses: [ { id, name, sudents: […], teachers: […], }, … ], }There is also another way.

In one of the projects, we encountered the issues with data organizing. To cope with that we can use Normalizr — a utility that normalizes data with nested objects.
Continue reading “Using Normalizr to organize data in stores — practical guide”

Simple Data Visualization with React JS: SVG Line Chart Tutorial

  • temp + Math.floor(random * 20) : temp – Math.floor(random * 20); data.push({x,y}) } return data; }render() { return ( div className=”App” // THIS IS WHERE OUR SVG CHART WILL RENDER /div ); }}export default App;I’m not going to extensively walk you through the function above as that’s not the focus of this tutorial.
  • The first four things we’ll need to know are the minimum and maximum x values in our data, and the minimum and maximum y values in our data.Before our render() function, add in these four functions:// GET MAX MIN X getMinX() { const {data} = this.props; return data[0].
  • y) + ” “;pathD += data.map((point, i) = { return “L ” + this.getSvgX(point.x) + ” ” + this.getSvgY(point.y) + ” “; });return ( path className=”linechart_path” d={pathD} style={{stroke: color}} / ); }Let’s break down the above code into smaller sections:First we create a variable named pathD and tell our line to move to the first x and y coordinate.
  • y) + ” “;Next, for each value in our data array, we will return a Line to the next x and y coordinate in the array.This line will be appended to the pathD variable.pathD += data.map((point, i) = { return “L ” + this.getSvgX(point.x) + ” ” + this.getSvgY(point.y) + ” “; });Finally, we return a path element with d equal to our pathD variable.You’ll notice I’ve also included a className and style element for making everything look pretty.return ( path className=”linechart_path” d={pathD} style={{stroke: color}} / );Create a Grid AxisThe last thing we’ll do in this tutorial is create a grid axis to pull everything together.If you think about it, a grid axis is simply two straight lines.
  • These coordinates are achieved by using our getSVGx() getSVGy() functions.We return each line.Returning the Axis Line GraphWe have everything we need, now we just need to return it to the parent element.render() { const {svgHeight, svgWidth} = this.props;return ( svg viewBox={`0 0 ${svgWidth} ${svgHeight}`} {this.makePath()} {this.makeAxis()} /svg ); }We’ll return an SVG element with a viewbox property that starts at x=0, and y=0, and goes to our SVG Height Width.Within our SVG we’ll return invocations of makePath() and makeAxis() which create our axis and line graph!Making it PrettyTo make it look pretty I added the following code to LineChart.css.linechart_path { stroke-width: 3; // Thick Line fill: none; // No Fill}.

Today we’ll be building a very simple line chart using React and SVG. In later tutorials we’ll add more complexities to this project: tooltips on hover, axis labels, etc. For this tutorial we’ll be…
Continue reading “Simple Data Visualization with React JS: SVG Line Chart Tutorial”

Extracting Logic from React Components

  • Right now to test formatting of amounts I have to create and mount a React component, but I should be able to just call that function and check the result.
  • Let’s create which will house the function that is currently in our component.
  • To test this, we can replace the body of ’s so that it just calls the new function from our module:

    Notice that I’ve still left the function defined on ; when pulling code apart like this you should do it in small steps; doing it like this decreases the chance of inadvertently breaking the code and also makes it easier to retrace your steps if something does go wrong.

  • Sure, the function is very straightforward for now, but as it grows we can now test it very easily without any need to fire up a React component to do so.
  • By looking through our components and finding standalone functions that we can pull out, we’ve greatly simplified our component whilst increasing our test coverage and clarity of our application greatly.

In the previous screencast we took a React component that was doing too much and refactored it, splitting it into two components that are easier to maintain, use and test. Although I’d recommend watching that video first, you don’t need to have watched it to read this blog post. You can find all the code on GitHub if you’d like to run it locally.
Continue reading “Extracting Logic from React Components”

Using Normalizr to organize data in stores — practical guide

Using Normalizr to organize data in stores — practical guide  #reactjs

  • Using Normalizr to organize data in stores — practical guideA React application usually needs some data from the server to be stored locally for immediate use, mainly to be shown on the page.
  • In the response for teachers we get something like this (shape of a server response): [ { students: [ { id, name, studentCourses: [ { studentId, courseId, grande, }, … ], }, … ], courses: [ { id, name, }, … ], }, … ]Here you can read about how to combine data in queries, if you also use Loopback.In this particular case this would spare us two requests, but this is not very useful if we speak about storing on front-end.
  • Secondly, we might need courses inside of a student entity instance, but when we make a query to the server, we don’t include these courses to avoid duplication.To cope with the described issues we can start with Normalizr — a utility that normalizes data with nested objects, just like in our case.
  • If you haven’t used redux-saga in your projects yet, I think this should convince you to do so.The first saga will fetch data:const urls = { teachers: ‘/teachers, students: ‘/students’, courses: ‘/courses’,};export function* fetchModel(model, ids, include) { const url = urls[model]; const where = {id: {inq: ids}}; const filter = {where, include}; const params = {filter}; return yield get({url, params});}The second will store the data:export function* queryModels(modelName, ids, include]) { const singleModelSchema = schema[modelName]; const denormalizedData = yield fetchModel(modelName, ids, include); const normalizedData = normalize(denormalizedData, [singleModelSchema]); const {entities} = normalizedData; yield a reducer will add new pieces of data to the already fetched ones:case ADD_ENTITIES: { const models = action.entities; const newState = cloneDeep(state); return mergeWith(newState, models);}Methods mergeWith and cloneDeep here are from lodash.Having done all that we can query data from server in this manner (selector):export function* fetchTeachers() { yield queryModels(‘teachers’, ids, [ { relation: ‘students’, scope: { include: [‘studentCourses’], } }, { relation: ‘courses’, } ]);}Normalizr uses a normalization schema as described here.Eventually we end up with the state that looks like this: state: { … models: { teachers: {…}, sudents: {…}, courses: {…}, studentCourses: {…}, }, … }This basically is a nice little copy of a part of our database in the store.
  • It is done in queryModels saga and we always know where the fetched data is going to be put.After that we can use it in any page of the app combing it in selectors as required.In our case, if needed, we can get an object for teacher as complicated as this (denormalized data): { students: [ { id, name, studentCourses: […], courses: […], }, … ], courses: [ { id, name, sudents: […], teachers: […], }, … ], }There is also another way.

In one of the projects, we encountered the issues with data organizing. To cope with that we can use Normalizr — a utility that normalizes data with nested objects.
Continue reading “Using Normalizr to organize data in stores — practical guide”