Home > Mobile >  Getting "TypeError: cannot read properties of undefined" but I'm getting 0 undefined
Getting "TypeError: cannot read properties of undefined" but I'm getting 0 undefined

Time:03-26

I have this function which is supposed to return then name of an item collection_name that exists within a users account. In this case the user is called hello. This api is return an object in this case so I'm turning it into an array using object.values. What am I doing wrong here? (also, the "hi" that's being returned is just a place holder, I intend to actually return the collection_name there.

import Spinner from '../Spinner';
import { useState, useEffect } from 'react';

function Badges() {
  const [assets, setAssets] = useState<any[]>();

  useEffect(() => {
    async function fetchData() {
      const res = await fetch(
        'https://proton.api.atomicassets.io/atomicassets/v1/accounts/hello'
      );
      const { data } = await res.json();
      setAssets(data);
    }
    fetchData();
  }, []);

  if (!assets) {
    return (
      <div>
        <Spinner />
      </div>
    );
  }

  const messageArray = Object.values(assets);

  return (
    <ul>
      {messageArray.map((result) => {
        const {
          0: {
            collection: { collection_name },
          },
        } = result;

        console.log(collection_name);

        return <>hi</>;
      })}
    </ul>
  );
}

export default Badges;

CodePudding user response:

Give this a shot. I think this is what you wanted? Might be completely off though :) Anyways, some notable changes were

  • Removed const messageArray = Object.values(assets);
  • Reworked the .map inside the return

You almost had it, although I think a big part of the confusion was caused by how the data was coming back from the API. The structure of the data seemed slightly confusing....at least to me. To avoid this issue in the future, you can always back your API responses with a TypeScript interface.

import Spinner from '../Spinner';
import { useState, useEffect } from 'react';


interface Assets { 
  collections: CollectionParent[];
  templates: Template[];
  assets: string;
}

interface Template {
  collection_name: string;
  template_id: string;
  assets: string;
}

interface CollectionParent {
  assets: string;
  collection: Collection;
}

interface Collection {
  allow_notify: boolean;
  author: string;
  authorized_accounts: string[];
  collection_name: string;
  contract: string;
  created_at_block: string;
  created_at_time: string;
  img: string;
  market_fee: number;
  name: string;
}

function Badges() {
  const [assets, setAssets] = useState<Assets>();

  useEffect(() => {
    async function fetchData() {
      const res = await fetch(
        "https://proton.api.atomicassets.io/atomicassets/v1/accounts/hello"
      );
      const { data } = await res.json();
      setAssets(data);
    }
    fetchData();
  }, []);

  if (!assets) {
    return (
      <div>
        <Spinner />
      </div>
    );
  }

  return (
    <ul>
      {assets?.collections?.length > 0 &&
        assets.collections.map((collectionParent, index) => {
          return (
            <li key={index}>{collectionParent.collection.collection_name}</li>
          );
        })}
    </ul>
  );
}

export default Badges;

  • Related