All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ducks.pages.sagas.mapUrlToRedux.ts Maven / Gradle / Ivy

There is a newer version: 7.28.3
Show newest version
import { all, call, select, put } from 'redux-saga/effects'
import { getLocation } from 'connected-react-router'
import { matchPath } from 'react-router-dom'
import queryString from 'query-string'
import { Action } from 'redux'
import compact from 'lodash/compact'
import head from 'lodash/head'
import map from 'lodash/map'
import isEmpty from 'lodash/isEmpty'
import each from 'lodash/each'
import isObject from 'lodash/isObject'

import { Location, Routes } from './types'

export function* mappingUrlToRedux(routes: Routes) {
    const location: Location = yield select(getLocation)

    if (routes) {
        yield all([
            call(pathMapping, location, routes),
            call(queryMapping, location, routes),
        ])
    }
}

export function* pathMapping(location: Location, routes: Routes) {
    const parsedPath = head(
        compact(map(routes.list, route => matchPath(location.pathname, route))),
    )

    if (parsedPath && !isEmpty(parsedPath.params)) {
        const actions = map(parsedPath.params, (value, key) => ({
            ...routes.pathMapping[key],
            ...applyPlaceholders(key, routes.pathMapping[key], parsedPath.params),
        }))

        for (const action of actions) {
            yield put(action as never)
        }
    }
}

export function* queryMapping(location: Location, routes: Routes) {
    const parsedQuery: Record = queryString.parse(location.search)

    if (!isEmpty(parsedQuery)) {
        const actions: Action[] = []

        for (const [key] of Object.entries(parsedQuery)) {
            const mapping = routes.queryMapping[key]

            if (mapping) {
                const action: Action = {
                    ...mapping.get,
                    ...applyPlaceholders(key, mapping.get, parsedQuery),
                }

                actions.push(action)
            }
        }

        for (const action of actions) {
            yield put(action)
        }
    }
}

export function applyPlaceholders(
    key: string,
    obj: Action | object,
    placeholders: Record,
): Record {
    const newObj: Record = {}

    each(obj, (v, k) => {
        if (isObject(v)) {
            newObj[k] = applyPlaceholders(key, v as object, placeholders)
        } else if (v === '::self') {
            newObj[k] = placeholders[key]
        } else if (placeholders[(v as string).substr(1)]) {
            newObj[k] = placeholders[(v as string).substr(1)]
        } else {
            newObj[k] = (obj as Record)[k]
        }
    })

    return newObj
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy