Home > database >  Access json data based on dynamic route nextjs
Access json data based on dynamic route nextjs

Time:12-28

I have a json file that contains content for several different pages that are under a "service" category. I use dynamic routes in nextJS by having a file as "[serviceId].tsx", this routing works. However I have a json file where I want to use the [serviceId] provided in the route to access information.

I have the following code in my [serviceId].tsx file:


    const json = jsonFile.services  
    const router = useRouter()
    const serviceId = router.query.serviceId
  

  return (
      <div> 
        <ArticleWithPicture title={content.title} description={content.description}/>
    </div>
  )
}

My json file looks similar to this (ive edited it to be more clear for this example):


        {
            "serviceId":
                [
                    {
                        "service1": {
                        "id": "xx",
                        "title": "xxx",
                        "description": "xx",
                        "featuredCompany":
                            [
                                { "id": "1", 
                                   "name": "xxx",
                                   "companyPageURL": "/",
                                   "imagePath": "xxx",
                                   "description": "xxx",
                                   "additionalServices": {
                                   "service1": "xxx",
                                   "service2": "xxx"
                                },
                                   "instagramURL":"/",
                                   "twitterURL": "/" 
                                }
                            ]
                        }           
                    },
                    {
                        "service2": {
                        "id": "xxx",
                        "title": "xxx",
                        "description": "xxx",
                        "featuredCompany":
                            [
                                { "id": "1", 
                                   "name": "xxx",
                                   "companyPageURL": "/",
                                   "imagePath": "xxx",
                                   "description": "xxx",
                                   "additionalServices": {
                                   "service1": "xxx",
                                   "service2": "xx"
                                },
                                   "instagramURL":"/",
                                   "twitterURL": "/" 
                                }
                            ]
                        }           
                    }                   
                ]
        }


Basically, each Service has the content for each indiviual page. So I want to dynamically set for instance the title of my component "ArticleWithPicture" based on the corresponding title in my json file based on the serviceId that I get from router.query.serviceId. However when I try the following code:

<ArticleWithPicture title={json.{serviceId}.title}/>

I get error (this is due to how I use "{}" within a "{}", is there a way to do this better?

But I also cannot access it if I do eg:

const title = json.serviceId.title

or (what is what I actually want to do ie: query the json file based on my serviceId provided by "router.query.serviceId")

const title = json.{serviceId}.title

I guess something might be wrong with either my json file structure or how I try to access it. Any advice would be appreciated.

Thanks!

CodePudding user response:

I'm assuming the JSON you provided is your entire jsonFile. If the JSON you provided is just jsonFile.services, then change any uses of jsonFile to jsonFile.services and update the type.

The format of the JSON isn't great for your use case because there's a lot of unnecessary wrapping.

With your current JSON

Assuming you cannot modify the format of the JSON, you would have to find the service from the serviceId array:

function getService(json, serviceId) {
  return json.serviceId
    .find((serviceWrapper) => serviceWrapper[serviceId] !== undefined)
    ?.service;
}

A fully typed example:

type Service = {
  id: string
  title: string
  description: string
  // ...
};

// you don't have to use this, I just included it for clarity
type JsonFile = {
  serviceId: {
    [serviceId: string]: Service
  }[]
};

function getService(json: JsonFile, serviceId: string): Service | undefined {
  return json.serviceId
    .find((serviceWrapper) => serviceWrapper[serviceId] !== undefined)
    ?.service;
}

// declare const jsonFile: JsonFile;

export default function ServicePage() {
  const router = useRouter();
  const serviceId = router.query.serviceId as string;

  const content = getService(jsonFile, serviceId);

  if (!content) return (
    <div>
      {'Article doesn\'t exist.'}
    </div>
  );

  return (
    <div>
      <ArticleWithPicture title={content.title} description={content.description} />
    </div>
  );
}

With better JSON

An example JSON that would need less unwrapping is:

{
  "service1": {
    "id": "xx",
    "title": "xxx",
    // ...
  },
  "service2": {
    "id": "xxx",
    "title": "xxx",
    // ...
  }
}
type JsonFile = {
  [serviceId: string]: Service
}

Then you would be able to just do jsonFile[serviceId] or jsonFile.services[serviceId] to get a service.

  • Related