Skip to content

11 Mutation Status

JP Barbosa edited this page Apr 28, 2021 · 5 revisions

Mutation Status

Components

Components

Add processing, success and error to useMutation hook

code ./src/hooks/useMutation.ts
import { useState } from 'react';
import ..., { AxiosError } from 'axios';
...

export const useMutation = <...>(...) => {
  const [processing, setProcesing] = useState<boolean>(false);
  const [success, setSuccess] = useState<boolean>();
  const [error, setError] = useState<AxiosError>();

  ...

  const wrap = (fn: Action<T>) => {
    return async (record: T) => {
      setProcesing(true);
      setSuccess(undefined);
      setError(undefined);
      fn(record)
        .then(() => {
          setSuccess(true);
          if (callback) {
            callback();
          }
        })
        .catch((error: Error) => {
          setSuccess(false);
          setError(error as AxiosError);
        })
        .finally(() => {
          setProcesing(false);
        });
    };
  };

  ...

  return {
    ...
    processing,
    success,
    error,
    setError,
  };
};

Add Processing, Success And Error to RecordMutations

code ./src/pages/Record/Mutations.tsx
import { useEffect } from 'react';
...
import { Status } from '../../components/Status';
import { RecordError } from '../../components/RecordError';

export const RecordMutations = <...>(...) => {
  const {
    ...,
    processing,
    success,
    error,
    setError,
  } = useMutation<T>(apiPath, callback);

  useEffect(() => {
    if (activeRecord.id) {
      setError(undefined);
    }
  }, [activeRecord, setError]);

  return (
    <div className="mutations">
      {error && <RecordError error={error} />}
      {activeRecord.id ? (
        <RecordEdit<T>
          ...
          success={success}
        />
      ) : (
        <RecordNew<T>
          ...
          success={success}
        />
      )}
      {processing && <Status text="Processing..." />}
    </div>
  );
};

Add Success RecordNewProps, RecordEditProps and RecordFormProps

code ./src/interfaces/PagesProps.ts
...

export interface RecordNewProps<T> {
  ...
  success?: boolean;
}

export interface RecordEditProps<T> {
  ...
  success?: boolean;
}

export interface RecordFormProps<T> {
  ...
  success?: boolean;
}

...

Add Success RecordNew

code ./src/pages/Record/New.tsx
...

export const RecordNew = <T extends Record>({
  ...
  success,
}: RecordNewProps<T>) => {
  return (
    <div className="new">
      <h2>New</h2>
      <RecordForm
        ...
        success={success}
      />
    </div>
  );
};

Add Success to RecordEdit

code ./src/pages/Record/Edit.tsx
...

export const RecordEdit = <T extends Record>({
  ...
  success,
}: RecordEditProps<T>) => {
  return (
    <div className="edit">
      ...
      <RecordForm
        ...
        success={success}
      />
    </div>
  );
};

Add Success to RecordForm

code ./src/pages/Record/Form.tsx
...

export const RecordForm = <T extends Record>({
  ...
  success,
}: RecordFormProps<T>) => {
  ...

  useEffect(() => {
    if (activeRecord.id || success) {
      setFormState(activeRecord);
    }
  }, [setFormState, activeRecord, success]);

  return (
    ...
  );
};

Add Validations to RecordError

code ./src/components/RecordError.tsx
...
import { ValidationError } from 'class-validator';

...

export const RecordError: React.FC<...> = (...) => {
  const validationErrors = error?.response?.data
    ?.validation as ValidationError[];

  return (
    <div className="error">
      ...
      {validationErrors &&
        validationErrors.map((error, errorKey) => (
          <ul key={errorKey}>
            {error.constraints &&
              Object.values(
                error.constraints
              ).map((constraint, constraintKey) => (
                <li key={constraintKey}>{constraint}</li>
              ))}
          </ul>
        ))}
    </div>
  );
};

Result

Result

Commit

git add .
git commit -m "Mutation Status"

Next step: Authors