Quantcast
Channel: ReScript Forum - Latest posts
Viewing all articles
Browse latest Browse all 2592

Merge tuples types

$
0
0

If each query returns a different type it’s nearly impossible to write a generic function for any scenario to combine all of the resulting data.

But if I understand correctly, your main goal is to have one single value describing your overall state of the queries (loading/done/error). If you don’t merge your resulting data together you could write a function which takes n query results and just returns the combined state. Handling the individual results would need to be done per request, since the query result is different for every query.

For example: ReScript Playground

type firestoreError
type queryResult<'documentdata> = (option<'documentdata>, bool, option<firestoreError>)

type overallState =
  | Loading({loading: int, done: int, error: int, errors: array<firestoreError>})
  | Done
  | Error(array<firestoreError>)
type abstractQueryResult = (option<unknown>, bool, option<firestoreError>)
external toAbstractQueryResult: queryResult<'a> => abstractQueryResult = "%identity"

let overallState: array<abstractQueryResult> => overallState = queries => {
  let (lc, dc, errs) = queries->RescriptCore.Array.reduce((0, 0, ([]: array<firestoreError>)), (
    s,
    q,
  ) => {
    let (lc, dc, errs) = s
    switch q {
    | (_, true, _) => (lc + 1, dc, errs)
    | (_, false, None) => (lc, dc + 1, errs)
    | (_, _, Some(err)) =>
      errs->RescriptCore.Array.push(err)
      (lc, dc, errs)
    }
  })
  if errs->RescriptCore.Array.length > 0 {
    Error(errs)
  } else if lc > 0 {
    Loading({loading: lc, done: dc, error: errs->RescriptCore.Array.length, errors: errs})
  } else {
    Done
  }
}

module ExampleUsage = {
  module Q1 = {
    type r = {name: string, age: int}
    type t = queryResult<r>
    let result: t = (Some({name: "me", age: 99}), false, None)
  }

  module Q2 = {
    type r = {weight: int, color: string}
    type t = queryResult<r>
    let result: t = (None, true, None)
  }

  module CombinedState = {
    let overallState =
      [Q1.result->toAbstractQueryResult, Q2.result->toAbstractQueryResult]->overallState
  }

  Console.log(CombinedState.overallState)
}

Viewing all articles
Browse latest Browse all 2592

Trending Articles