The Journey of #100DaysOfCode (@sourabhbagrecha)

#Day58 of #100daysofcode

So, to bring this idea to life I teamed up with @Andrew_Meyer, who is one of the top contributors of our Atlas Device Sync’s Realm SDK for React Native.
Basically, we are creating JavaScript a library that can be installed using npm which will act as a bridge between our Realm SDK and the function where the developer wants to perform analytics and get insights from the data stored on the user’s device.

Given, that we already know the input & the expectations from this library, we chose the Test Driven Development approach.

The current MongoDB aggregation framework has more than 150 expressions and 30 stages. But we can not cover everything in these 5 days. Therefore, we will start with the most common and fundamental stages:

  1. $match
  2. $group
  3. $project
  4. $addFields
  5. $sort
  6. $limit
  7. $skip

And we will be covering as many edge cases as possible.

4 Likes

#Day59 of #100daysofcode

Today we implemented a few of the aggregation stages mentioned in my previous post. Along with adding test cases for different types of queries and scenarios, we also added a few failure test cases to ensure that our stage implementation throws an Invalid Input error when required and it doesn’t affect the other parts of the library.
Some stages were pretty easy to implement like $skip & $limit, while some of them took a lot of prototyping like $group & $project.

2 Likes

#Day60 of #100daysofcode

Today I implemented a few operators like $add, $multiply, $divide etc. I also implemented a recursion logic to resolve deeply nested functions so that we can perform the calculations at any depth with any number of operators and expressions without hardcoding any special case.
All of these operators first got tested using the $group accumulators but we are now refactoring them into individual, independent functions that can be used & tested in other stages like $addFields and $project.

2 Likes

#Day61 of #100daysofcode

Today we published our first ever alpha release of our realm-aggregate package. Everything went as per our plan during the skunkworks, initially, I was a bit scared seeing the number of stages, operators, and expressions, but once we got the basic setup done(which took about the first three days), adding new features and functionalities became very easy.

@Andrew_Meyer 's 13 years of development experience played a really important role in getting our package published, I learned a lot while collaborating with him.
If you are curious to know what we built, take a look at our GitHub Repository:

If you would like to contribute, please feel free to do so, by creating a pull request on the same.

If you want to leverage these capabilities in your JavaScript application, install this package by executing:

npm i realm-aggregate

We wrapped up our skunkworks by submitting a 3-minute video demo explaining all the things features and things we implemented during this week.

3 Likes

#Day62 of #100daysofcode

Today I implemented our realm-aggregate package in my React Native based expense manager called expengo.
And using this I extracted all the insights that I need to build an analytics dashboard even without an internet connection.

3 Likes

#Day63 of #100daysofcode

Today I learned how to use the React provided useMemo hook along with useCallback in order to optimise the performance of my React app by only running expensive functions and complex calculations when a any of the dependencies mention in the dependency array changes.

2 Likes

#Day64 of #100daysofcode

Today I started implementing the Profile screen my expengo mobile app.
I will fetch and store all the user specific non sensitive data into local storage from Atlas App Services Authentication and will display it in the profile screen.

2 Likes

#Day65 of #100daysofcode

Today I learned about React M.js Design patters. In the next few days I will covering all the possible design patterns that can be used to increase the developer productivity and makes our code readable and easily understandable depending on the use case without the overhead of maintaining our own framework.

2 Likes

#Day66 of #100daysofcode

Today I learned about the Context Module React pattern where one can use different modules within an application and using this we can create multiple contexts that will be used within an specified part(boundary) pf the application.

2 Likes

#Day67 of #100daysofcode

Today I implemented my Context Module pattern learning into an app. So basically, it allows us to encapsulate a complex set of state changes into a utility function which can be tree-shaken and lazily loaded.

Instead of just exporting the Provider & Context, we can also export that utility to make the logic less prone to errors(which can be introduced by typos in dispatch action names).

Take a look at the following code to learn more:

function UserProvider({children}) {
  const {user} = useAuth()
  const [state, dispatch] = React.useReducer(userReducer, {
    status: null,
    error: null,
    storedUser: user,
    user,
  })
  const value = [state, dispatch]
  return <UserContext.Provider value={value}>{children}</UserContext.Provider>
}

function useUser() {
  const context = React.useContext(UserContext)
  if (context === undefined) {
    throw new Error(`useUser must be used within a UserProvider`)
  }
  return context
}

async function updateUser(dispatch, user, updates) {
  dispatch({type: 'start update', updates})
  try {
    const updatedUser = await userClient.updateUser(user, updates)
    dispatch({type: 'finish update', updatedUser})
    return updatedUser
  } catch (error) {
    dispatch({type: 'fail update', error})
    return Promise.reject(error)
  }
}

// Exporting utility along with the default exports for a regular context
export {UserProvider, useUser, updateUser}
2 Likes

#Day68 of #100daysofcode

Today I learned about the Compound Component React pattern. Compound components are components that work together to form a complete UI. I am working on an example that uses this React Pattern and will share the implementation tomorrow.

2 Likes

#Day69 of #100daysofcode

Today I finished implementing a Compound Component, which provides a set of components that implicitly share state for a simple yet powerful declarative API for reusable components.

In the following example, we are sharing the on & toggle values across different components implicitly, that’s making our App component really extensible and declarative.

import * as React from 'react'
import {Switch} from '../switch'

function Toggle(props) {
  const [on, setOn] = React.useState(false)
  const toggle = () => setOn(!on)

  return React.Children.map(props.children, child => {
    return React.cloneElement(child, {
      on,
      toggle,
    })
  })
}

const ToggleOn = ({on, children}) => (on ? children : null)
const ToggleOff = ({on, children}) => (on ? null : children)
const ToggleButton = ({on, toggle}) => <Switch on={on} onClick={toggle} />

function App() {
  return (
    <div>
      <Toggle>
        <ToggleOn>The button is on</ToggleOn>
        <ToggleOff>The button is off</ToggleOff>
        <ToggleButton />
      </Toggle>
    </div>
  )
}

export default App
3 Likes

#Day70 of #100daysofcode

Today I learned about Flexible Compound Component React-Pattern, which is basically a level ahead of Compound Component in which it provides the ability to nest components at any level.
Now, these kind of requirements in React usually requires you to perform prop drilling to the complete depth just so that you can provide a value to the bottom-most component, but React Context comes pretty helpful in those cases, therefore, in the following example I will be using this React Pattern to share implicit state between deeply nested components as well using React’s Context API:

const ToggleContext = React.createContext()

function Toggle({children}) {
  const [on, setOn] = React.useState(false)
  const toggle = () => setOn(!on)

  return (
    <ToggleContext.Provider value={{on, toggle}}>
      {children}
    </ToggleContext.Provider>
  )
}

function ToggleOn({children}) {
  const {on} = React.useContext(ToggleContext)
  return on ? children : null
}

function ToggleOff({children}) {
  const {on} = React.useContext(ToggleContext)
  return on ? null : children
}

function ToggleButton({...props}) {
  const {on, toggle} = React.useContext(ToggleContext)
  return <Switch on={on} onClick={toggle} {...props} />
}

function App() {
  return (
    <div>
      <Toggle>
        <ToggleOn>The button is on</ToggleOn>
        <ToggleOff>The button is off</ToggleOff>
        <div>
          <ToggleButton />
        </div>
      </Toggle>
    </div>
  )
}

2 Likes

#Day71 of #100daysofcode

Today I added custom hook validation to my Flexible Compound Component to avoid any runtime errors that might get caused due to invalid usage of ToggleContext.
Here’s a snippet that demonstrates the implementation of the custom useToggle hook and how it gets consumed in the children component.

function useToggle() {
  const context = React.useContext(ToggleContext)
  if (!context) throw Error('useToggle must be consumed within <Toggle/>')
  return context
}

function ToggleOn({children}) {
  const {on} = useToggle()
  return on ? children : null
}
3 Likes

#Day72 of #100daysofcode

Today I learned about the Prop Collections and Getters Pattern, which allows our hook to support common use cases for UI elements people build with our hook.
This is especially useful when we want to make our UI components that ensures Accessibility standards.

function useToggle() {
  const [on, setOn] = React.useState(false)
  const toggle = () => setOn(!on)

  return {on, toggle, togglerProps: {'aria-pressed': on, onClick: toggle}}
}

function App() {
  const {on, togglerProps} = useToggle()
  return (
    <div>
      <Switch on={on} {...togglerProps} />
      <hr />
      <button aria-label="custom-button" {...togglerProps}>
        {on ? 'on' : 'off'}
      </button>
    </div>
  )
}
2 Likes

#Day73 of #100daysofcode

Today my best friend @anshul_bhardwaj has also joined us in this adventure of #100daysofcode.
He is on his way to become a full-stack developer in the next few months, wish him luck.

As of my updates for today, I learned about prop-getters.
Sometimes the users of our hook might want to implement their own functions while at the same time they want to leverage all the props that our hooks provide by default, therefore we need to provide an API that will provide them the ability to add custom features that they want to be executed combinedly with the defaults.

In the following example, we are providing the ability to execute a custom onClick function alongside the default toggle function.

function useToggle() {
  const [on, setOn] = React.useState(false)
  const toggle = () => setOn(!on)

  return {
    on,
    toggle,
    getTogglerProps: ({onClick, ...props} = {}) => {
      return {
        'aria-pressed': on,
        onClick: () => {
          toggle()
          onClick()
        },
        ...props,
      }
    },
  }
}

function App() {
  const {on, getTogglerProps} = useToggle()
  return (
    <div>
      <Switch on={on} {...getTogglerProps()} />
      <hr />
      <button
        aria-label="custom-button"
        {...getTogglerProps({
          onClick: () => {
            console.log(
              `Calling inside a function that's passed to prop getters,
               to execute apart from the defaults provided by prop collections.`,
            )
          },
        })}
      >
        {on ? 'on' : 'off'}
      </button>
    </div>
  )
}
2 Likes

#Day74 of #100daysofcode

Today I learned about the State Reducer React Pattern, I have started implementing it in an example component and I think what it basically does is, it inverts the control over the state management of our hook to the developer utilizing it. I will post a detailed implementation for this pattern tomorrow.

1 Like

#Day75 of #100daysofcode

Yay! Today I implemented the State Reducer React Pattern in a custom React Hook.
Let’s see this pattern in action.

Suppose we have a state reducer function as below, which basically updates the state based on the “actionType” provided to it.

function toggleReducer(state, {type, initialState}) {
  switch (type) {
    case 'toggle': {
      return {on: !state.on}
    }
    case 'reset': {
      return initialState
    }
    default: {
      throw new Error(`Unsupported type: ${type}`)
    }
  }
}

Now, by using this reducer we are going to implement a custom hook called useToggle that we can use across other components in our app.

function useToggle({initialOn = false, reducer = toggleReducer} = {}) {
  const {current: initialState} = React.useRef({on: initialOn})
  const [state, dispatch] = React.useReducer(reducer, initialState)
  const {on} = state

  const toggle = () => dispatch({type: 'toggle'})
  const reset = () => dispatch({type: 'reset', initialState})

  ... ...

  return {
    on,
    reset,
    toggle,
    getTogglerProps,
    getResetterProps,
  }
}

Finally, we are going to use this hook in our App component.

function App() {
  const {on, getTogglerProps, getResetterProps} = useToggle()
  return (... Some JSX here ...)
}

But what if I (as the user of this hook) want to implement a custom reducer instead of the default toggleReducer used by the useToggle hook?

I can simply pass a custom reducer in the argument to the useToggle hook like this:

function App() {
  const [timesClicked, setTimesClicked] = React.useState(0)
  const clickedTooMuch = timesClicked >= 4

  function toggleStateReducer(state, action) {
    switch (action.type) {
      case 'toggle': {
        if (clickedTooMuch) {
          return {on: state.on}
        }
        return {on: !state.on}
      }
      case 'reset': {
        return {on: false}
      }
      default: {
        throw new Error(`Unsupported type: ${action.type}`)
      }
    }
  }

  const {on, getTogglerProps, getResetterProps} = useToggle({
    reducer: toggleStateReducer,
  })

  return (... Some JSX here ...)
}

And that just works flawlessly.

3 Likes

#Day76 of #100daysofcode

Today I learned about the Control Props React Pattern, it’s been the toughest React Pattern I have ever come across. I am still wrapping my head around this. I have tried an example using this pattern but it seems like I have to revisit this concept, again and again, to understand it fully.
Therefore I will give it a few more tries tomorrow and hopefully I will be able to grasp it properly.

3 Likes

Hi @SourabhBagrecha,

Congrats on passing the 3/4 mark i(75 days!) in your challenge! :fire:

You’ve earned the rare Coding Legend badge!

Thanks for sharing … keep up the great journey!

Regards,
Stennie

5 Likes