GenomeJS
Core

getTrait()

Read the current resolved value of a primitive or derived Genome token.

getTrait() returns the current resolved value associated with one Genome token name.

Signature

genome.getTrait(
  name: string,
): Primitive

Parameters

ParameterTypeDescription
namestringName of the primitive or derived token to read

Return value

type Primitive = string | number;

The returned value is the current resolved value stored in the Genome’s DNA.

Reading a primitive

const genome = new Genome({
  primitives: {
    spacing: 16,
  },

  tokens: {},
});

genome.getTrait("spacing");
// 16

Reading a derived token

const genome = new Genome({
  primitives: {
    spacing: 16,
  },

  tokens: {
    sectionGap: (dna) => `${Number(dna.spacing) * 4}px`,
  },
});

genome.getTrait("sectionGap");
// "64px"

Reading after mutation

getTrait() always reads the latest resolved value.

const genome = new Genome({
  primitives: {
    spacing: 16,
  },

  tokens: {
    gap: (dna, context) => {
      const scale = typeof context.scale === "number" ? context.scale : 1;

      return `${Number(dna.spacing) * scale}px`;
    },
  },
});

genome.getTrait("gap");
// "16px"

genome.mutate({
  scale: 1.5,
});

genome.getTrait("gap");
// "24px"

Reading inside a subscription

const unsubscribe = genome.subscribe(() => {
  const gap = genome.getTrait("gap");

  console.log(gap);
});

genome.mutate({
  scale: 1.25,
});

Subscribers do not receive a value argument. Read the required traits with getTrait() inside the listener.

Unknown token behavior

Calling getTrait() with a name that is not present in the resolved DNA throws an error.

genome.getTrait("missingToken");

Current error message:

Unknown token: "missingToken"

The thrown value is currently a standard Error, not UnresolvedTokenError.

UnresolvedTokenError is used when a token function references a missing DNA value during graph compilation.

Primitive and token names share one namespace

Primitives and derived tokens are combined into one resolved DNA object.

const genome = new Genome({
  primitives: {
    baseSpacing: 16,
  },

  tokens: {
    spacing: (dna) => `${dna.baseSpacing}px`,
  },
});

Both values are available:

genome.getTrait("baseSpacing");
// 16

genome.getTrait("spacing");
// "16px"

Avoid using the same name for a primitive and a token.

TypeScript return type

The return type is the broad Primitive union:

string | number;

GenomeJS does not currently infer a different return type for every token name.

Narrow or convert the result when necessary:

const value = genome.getTrait("spacing");

const spacing = typeof value === "number" ? value : Number.parseFloat(value);

For styles, conversion to a string is often sufficient:

const color = useGenomeTrait(genome, "buttonColor");

return (
  <button
    style={{
      backgroundColor: String(color),
    }}
  >
    Continue
  </button>
);

Server usage

getTrait() works when the Genome has no DOM target:

const genome = new Genome(
  {
    primitives: {
      message: "Hello",
    },

    tokens: {},
  },
  null,
);

genome.getTrait("message");
// "Hello"

CSS expression requires an element, but value resolution and trait reads do not.

Reading generated CSS names

getTrait() uses the original JavaScript token name:

genome.getTrait("buttonColor");

Not the generated CSS custom-property name:

genome.getTrait("--g-button-color");
// throws

The mapping is:

JavaScript name: buttonColor
CSS property:    --g-button-color

Error behavior

getTrait() throws when the supplied name does not exist in the current DNA.

try {
  genome.getTrait("missing");
} catch (error) {
  console.error(error);
}

It does not return:

undefined;

This helps catch spelling mistakes and invalid assumptions early.

Notes

  • Reads are synchronous.
  • The method returns strings or numbers.
  • Both primitives and derived tokens are readable.
  • The name must use the original configuration key.
  • An unknown name throws instead of returning undefined.
  • Reading a value does not create a subscription.

On this page