Loaders in the frontend frameworks

📘

This is an article for advanced users of Frontastic.

Loaders in the Frontastic frontend framework are used to make modifications to backend data, for example, adding a product to the cart or logging in a user. In this article, we'll show you how to use them and display the feedback from them to the user.

The general idea

The loaders can be retrieved from the application to handle all operations regarding, for example, the user account, cart, and wishlist.

An example of what a full component using loaders, data resulting from loader actions, and informs the customer about potential errors could look like:

import React, { Component } from 'react'
import PropTypes from 'prop-types'

import AtomsInput from '...'
import AtomsButton from '...'

import app from '@frontastic/catwalk/src/js/app/app'
import Notifications from '@frontastic/catwalk/src/js/component/notifications'

class Login extends Component {
    constructor (props) {
        super(props)

        this.state = {
            login_email: '',
            login_password: '',
        }
    }

    render () {
        if (this.props.context.session.loggedIn) {
            return false
        }

        return (<form className='c-form'>
            <Notifications />
            <AtomsInput label='Email' type='email'
                value={this.state.login_email}
                onChange={(event) => {
                    this.setState({ login_email: event.target.value })
                }}
            />
            <AtomsPassword label='Password' type='password'
                value={this.state.login_password}
                onChange={(event) => {
                    this.setState({ login_password: event.target.value })
                }}
            />
            <AtomsButton type='primary' full
                onClick={(event) => {
                    app.getLoader('context').login(
                        this.state.login_email,
                        this.state.login_password
                    )
                }}>
                Login
            </AtomsButton>
        </form>)
    }
}

Login.propTypes = {
    context: PropTypes.object.isRequired,
}

export default tastify({
    connect: {
        context: true,
    }
})(Login)

We'll look into 3 important topics in more detail:

  1. Retrieving the current state using tastify (line 56)
  2. Changing the state on the server using app.getLoader(...).<action>(...) (line 41)
  3. Displaying notifications using the <Notifications /> helper component (line 26)

1. Using Tastify

While you can connect directly to the Redux state tastify is the optimized way to access the relevant information and we'll ensure this API stays backwards compatible. Especially the 3 most important concerns regarding loaders can be retrieved using Tastify: context, cart and wishlist. You'll find more info about tastify in this article.

2. Using the loaders

Loaders in Frontastic allow you to modify information in the connected backend systems. All loaders can be retrieved using the app.getLoader(...) function from @frontastic/catwalk/src/js/app/app as you can see in the full example above. The result from the loader will be handled by Frontastic and you can expect your component to be updated accordingly.

Cart

The cart loader is used to modify the cart, add items, and additional information to it. The available methods are:

  • Cart::get(parameters = {}) – Explicitly get the cart again but usually isn't necessary
  • Cart::getOrder(parameters = {}) – Retrieve a certain order from the backend but usually isn't necessary
  • Cart::setProductOption(productId, option) – Set additional options on a variant line item in the cart identified by its product ID (this is only used for special cart items)
  • Cart::add(product = null, variant, count, option = null) – Add a variant line item to the cart
  • Cart::addMultiple(lineItems) – Add multiple line items to the cart at once
  • Cart::addPayment(cartInformation) – Add payment information to the cart
  • Cart::updateLineItem(update) – Update a line item in the cart (most likely its count)
  • Cart::removeLineItem(update) – Remove line item from cart
  • Cart::updateCart(cartInformation) – Update cart information, like shipping or billing addresses or any other of the available fields
  • Cart::redeemDiscount(code) – Add a discount code to the cart
  • Cart::removeDiscount(discountId) – Remove a discount code from the cart
  • Cart::checkout(cartInformation) – Try to convert the cart into a placed order (this will only work on "completed" carts (all information available and paid))

Account (Context)

The context loader is used for all account-related actions, from register and login to managing the user's addresses. The available methods are:

  • Context::refresh(parameters) – Update the user context (login state) (called automatically on log in and register)
  • Context::register(user, redirect = true) – Register a new user
  • Context::login(email, password, previous = null) – Log in a user with the provided credentials
  • Context::logout() – Log out a user
  • Context::addAddress(address) – Add an address to the user's address list
  • Context::updateAddress(address) – Update an existing address
  • Context::removeAddress(address) – Remove an address from the list
  • Context::setDefaultBillingAddress(address) – Set an address as the default billing address
  • Context::setDefaultShippingAddress(address) – Set an address as the default shipping address
  • Context::updateUser(user) – Update user information
  • Context::requestPasswordReset(email) – Request a password reset for a user
  • Context::resetPassword(token, newPassword) – Reset the password to a new password with the password request token the user retrieved by mail
  • Context::updatePassword(oldPassword, newPassword) – Update the users password (with the old and new password)
  • Context::notifyUser(message, type = 'info', timeout = 5000) – Notify a user about something (most actions, and even cart actions, do this automatically. This can include user-focused errors.)

Wishlist

The wishlist loader is used to manage the products on the user's wish list and the list of available wish lists if there are multiple. The available methods are:

  • Wishlist::get(parameters = {}) – Explicitly get the wish list again but usually isn't necessary
  • Wishlist::create(name) – Create another wishlist with the given name
  • Wishlist::add(product, variant, count, wishlist = null) – Add a product (line item) to a wishlist
  • Wishlist::addMultiple(lineItems) – Add multiple products (line items) to a wishlist at once
  • Wishlist::updateLineItem(wishlist, update) – Update a line item inside the wishlist
  • Wishlist::removeLineItem(wishlist, update) – Remove a line item from a wishlist

3. Using the notifications helper

The <Notifications /> helper component from @frontastic/catwalk/src/js/component/notifications displays all user notifications. It can be embedded anywhere on the page and will always display all pending notifications. Some notifications (success) will automatically hide again after 5 seconds, while some notifications will stay until the user removes them (errors).

You can overwrite the default AtomsNotification by using the component injector. For this, you could add something similar to the below to your src/js/injection.js:

import MyNotification from 'my/notification'

ComponentInjector.set('AtomsNotification', MyNotification)

A good way to use this component could be either to embed this in every form or just embed this into a commonly used header component.

See the injecting custom components and reducers article for more info on the component injector.