Tips for extracting information from a TypeScript JSON document

Hey there, I'm currently having trouble understanding how to retrieve data from a JSON file.

environment.ts:

    export const environment = {
  production: false,
  urlListBooks: "/assets/list-books.json",
  urlGetBooks: "/assets/edit-book.json?:id",
  urlGetTags: "/assets/edit-book.json?:tags",
  urlPostBooks: "/assets/edit-book.json",
  urlListTags: "/assets/list-tags.json",
  urlPostTags: "/assets/edit-tag.json"
};

edit-book.json:

"book":{
    "id": 1,
    "title": "The Shining",
    "authorId": 1,
    "tags": [{"name":"new"}, {"name":"test"}]
},
"authors":[
    {
        "id": 1,
        "prename": "Stephen",
        "surname": "King"
    },
    {
        "id": 3,
        "prename": "Algernon",
        "surname": "Blackwood"
    },
    {
        "id": 4,
        "prename": "Edgar Allan",
        "surname": "Poe"
    },
    {
        "id": 5,
        "prename": "Howard Phillips",
        "surname": "Lovecraft"
    }
],
"tags":[
    {
        "name": "new"
    },
    {
        "name": "Horror"
    },
    {
        "name": "Romance"
    }
]

}

service:

  getBookTags(n: String) Observable<Tag[]>{
    return this.http.get<Tag[]>(environment.urlGetTags.)
  }

I want the function getBookTags(n: String) to return the tags array of the book with the title n as defined in edit-book.json (for example, "tags": [{"name":"new"}, {"name":"Horror"}]) so that I can use it later to check which tags a book has and select them.

Your assistance on this matter would be greatly appreciated :)

Answer №1

Alright, I believe I have solved the issue you were facing. Let me walk you through my thought process so you can understand the objective. You can find my solution by following this link: https://codesandbox.io/s/thirsty-minsky-g6959f?file=/assets/edit-book.json:0-752

First off, the JSON data provided doesn't seem quite right. It shows multiple authors but only one "book". I assume you actually want multiple books instead. Also, make sure to wrap it within curly braces as demonstrated below:

{
  "books": [
    {
      "id": 1,
      "title": "The Shining",
      "authorId": 1,
      "tags": [{ "name": "new" }, { "name": "test" }]
    },
    {
      "id": 2,
      "title": "The Wendigo",
      "authorId": 2,
      "tags": [{ "name": "Horror" }]
    }
  ],
  "authors": [
    {
      "id": 1,
      "prename": "Stephen",
      "surname": "King"
    },
    {
      "id": 3,
      "prename": "Algernon",
      "surname": "Blackwood"
    },
    {
      "id": 4,
      "prename": "Edgar Allan",
      "surname": "Poe"
    },
    {
      "id": 5,
      "prename": "Howard Phillips",
      "surname": "Lovecraft"
    }
  ],
  "tags": [
    {
      "name": "new"
    },
    {
      "name": "Horror"
    },
    {
      "name": "Romance"
    }
  ]
}

Next, in your Typescript code, let's establish typings for the JSON data you'll be fetching. This will enhance readability, provide intellisense, and help catch errors beforehand. Define the properties of the JSON like so:

type Tag = {
  name: string;
};

type Book = {
  id: number;
  title: string;
  authorId: number;
  tags: Tag[];
};

type Author = {
  id: number;
  prename: string;
  surname: string;
};

type BookData = {
  books: Book[];
  authors: Author[];
  tags: Tag[];
};

In essence, we have bookdata comprised of books, authors, and tags. Each entity has its own set of properties defined under their respective types.

Now onto the actual implementation, we'll utilize the fetch API to retrieve the JSON data from the specified URL.

async function getBookTags(n: string): Promise<Book[]> {
  return fetch(url)
    .then<BookData>((res) => res.json())
    .then((data) => data.books)
    .then((books) => books.filter((b) => doesBookHaveTag(b, n)));
}

The initial step involves fetching the data via the API, resulting in a promise. Upon resolution, we parse the response into JSON format. Subsequently, after another promise resolution, we filter out books based on matching tags.

The helper function doesBookHaveTag is simply designed to determine if a book contains a specific tag:

function doesBookHaveTag(book: Book, n: string): boolean {
  // check if book has at least one tag matching n
  return book.tags.some((t) => t.name.toLowerCase() === n.toLowerCase());
}

If promises are unclear, consider watching tutorials to grasp the concept. Essentially, the browser sends an http request which resolves into executing functions specified within .then when there's availability. To call your async function and log all books tagged as "horror", execute the following:

getBookTags("horror").then(console.log); // displays the relevant book

This should elucidate how to retrieve data, handle its promise, and define your responses. While Angular specifics may vary (I'm more proficient with React), the core principles discussed apply universally to Javascript/Typescript coding.

[endnote]: When referring to a function in .then, it implies passing a function inside the .then method. For instance, data => data.books signifies a function, equivalent to:

function(data: BookData): Book[] {
    return data.books
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

breaking down ajax json responses

I am attempting to extract specific data from a JSON response provided by a web service using the code below. function getADData() { var strSearch = $('#txtSearch').val() var ajaxData = "{ 'PartNameString': &apo ...

The ideal version of firebase for showing messages in the foreground

Looking to instantly display notifications as soon as they are received? I recently watched a video on Angular 8 + Firebase where version 7.6.0 was discussed. While the notification is displayed in the foreground for me, I find that I need to click on some ...

The process of obtaining the selected option with ElementRef

One of the features in my table is the ability to add dynamic rows using an ADD button. I used a form array to create this table structure. Each row includes a select box with a list of options. Situation When a user selects an option from the select b ...

Struggling with retrieving information from a local JSON file using React

I am encountering an issue in my React project while trying to access a local JSON file located in the src folder using fetch. [ { "id": 1, "field1": "some data", "field2": 63, "field3": ...

Utilizing HTML5 data attributes to store intricate JSON objects and manipulate them using JavaScript

Recently, I encountered a unique challenge that I set for myself... I am currently in the process of developing an advanced ajax content loader plugin that comes with an array of options and callbacks. In order to streamline the initialization process and ...

Converting JSON to POJO using GSON fails to retrieve the value and returns as null

Greetings, I've recently started using the Loopj and GSON libraries for handling Web Service responses. However, I'm facing some difficulties in extracting values from GSON to my POJO. I'm struggling to understand how to retrieve values fro ...

Several values are not equal to the typeorem parameter

I am looking for a way to create a Typeorm query that will return results similar to the following SQL statement: SELECT * FROM Users WHERE id <> 3 and id <> 8 and id <> 23; Any suggestions on how I can achieve this? Thank you! ...

JSONP request resulted in a syntax error

I'm having trouble retrieving data from a JSONP source, as it keeps throwing a Syntax error when the function is called. I am quite new to this subject and find it hard to understand why this error occurs. It seems like my understanding of JSONP reque ...

Guide for Uploading, presenting, and storing images in a database column with the help of jQuery scripting language

What is the best method for uploading, displaying, and saving an image in a database using jQuery JavaScript with API calls? I am working with four fields in my database: 1. File ID 2. Filename 3. Filesize 4. Filepath ...

real-time parsing of JSON responses using PHP

I am currently conducting research for my graduate program in finance on the topic of crypto currencies such as bitcoin. I am focusing on extracting individual data from JSON responses provided by the cryptsy API, which is a platform for trading crypto cur ...

Design system styled component - "The type of X cannot be explicitly defined without a reference..."

How can I resolve this TypeScript issue? I have a styled component exported from a style.ts file and used in the index.tsx file of my React component: style.ts: import { styled, Theme } from '@mui/material/styles'; type CardProps = { theme? ...

The seamless merging of Angular2, TypeScript, npm, and gulp for enhanced development efficiency

I'm fairly new to front-end development and I am currently working on an application using Angularjs2 with TypeScript in Visual Studio 2015. I have been following the steps outlined in this Quickstart https://angular.io/docs/ts/latest/cookbook/visual- ...

Utilizing JavaScript files within Angular2 components: A guide

I need to insert a widget that runs on load. Typically, in a regular HTML page, I would include the script: <script src="rectangleDrawing.js"></script> Then, I would add a div as a placeholder: <div name="rectangle></div> The is ...

Blurry text issue observed on certain mobile devices with Next.js components

There continues to be an issue on my NextJS page where some text appears blurry on certain mobile devices, particularly iPhones. This problem is only present on two specific components - both of which are interactive cards that can be flipped to reveal the ...

What could be the reason for Typescript attempting to interpret files in the `./build` directory as input files?

After struggling for an hour on this issue, I am stuck. The variables outDir and rootDir are set. However, the problem arises when only src is included in include, TypeScript shows the configuration via showConfig, yet it's attempting to compile 4 fi ...

Bringing elements into perfect harmony in Angular

Seeking guidance on HTML alignment using bootstrap for prebuilt components like buttons. Struggling with aligning divs and looking to learn more about grouping them together for proper alignment. Goal is to center elements on screen one above the other. ...

The onClick function for a button is not functioning properly when using the useToggle hook

When the button is clicked, it toggles a value. Depending on this value, the button will display one icon or another. Here is the code snippet: export const useToggle = (initialState = false) => { const [state, setState] = useState(initialState); c ...

Cross-Origin Resource Sharing Problem - Angular version 8 with NodeJS and ExpressJS

I've attempted various solutions from different sources and have a feeling that I may be overlooking something minor here. In my setup, I have an AngularJS 8 application running on Node 10 with ExpressJS. The specific issue I'm encountering rela ...

The JSON array data is coming back as undefined

Currently facing an issue with the data sa var data = '[{"idcoupons_tbl":"1","discount_percent":"10"}]'; Every time I attempt to parse and retrieve a discount_percent, ie var result= jQuery.parseJSON(data); alert(result["discount_percent"]); ...

Error: Bitbucket pipeline does not have the necessary permissions to complete the operation

I encountered an error while building ng build on Bitbucket. My backend is Firebase. Can you help me figure out what I'm doing wrong? EPERM: operation not permitted, lchown '/opt/atlassian/pipelines/agent/build/node_modules/.cache/angular-buil ...