简体   繁体   English

如何获取 JSON 文件的数据(打字稿)

[英]How to get data of a JSON file (typescript)

Hi I got a bit stuck at trying to understand how to fetch data of a JSON file.嗨,我在尝试了解如何获取 JSON 文件的数据时遇到了一点困难。

environment.ts:环境.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:编辑书.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.)
  }

what I want getBookTags(n: String) to do is returning the tags array of the book with title n defined in the edit-book.json (eg "tags": [{"name":"new"}, {"name":"Horror"}] ) so that I can later use the function to check which tags a book has and select them.我想要 getBookTags(n: String) 做的是返回在 edit-book.json 中定义的标题为 n 的书的标签数组(例如“tags”:[{“name”:“new”},{“name ":"Horror"}] ) 这样我以后就可以使用 function 检查一本书有哪些标签和 select 它们。

Your help would be very appreciated:)非常感谢您的帮助:)

Ok I think I've solved this for you, I'm going to walk through my process with you so you understand what the goal is.好的,我想我已经为您解决了这个问题,我将与您一起完成我的流程,以便您了解目标是什么。 You can see my solution here: https://codesandbox.io/s/thirsty-minsky-g6959f?file=/assets/edit-book.json:0-752你可以在这里看到我的解决方案: https://codesandbox.io/s/thirsty-minsky-g6959f?file=/assets/edit-book.json:0-752

First thing is that your JSON you provided doesn't really make much sense, it shows multiple authors and just one "book".首先,您提供的 JSON 并没有多大意义,它显示了多个作者和一本“书”。 I think instead you want multiple books.我认为你想要多本书。 Secondly, it's gotta be wrapped in a curly brace as shown:其次,它必须用大括号包裹起来,如下所示:

{
  "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"
    }
  ]
}

Now, in your Typescript code we want to have typings for the json you're going to fetch.现在,在您的 Typescript 代码中,我们希望为您要获取的 json 打字。 This will make your code more readable, it will give you intellisense, and help you catch some errors before you try to run your code.这将使您的代码更具可读性,它会为您提供智能感知,并帮助您在尝试运行代码之前捕获一些错误。 So we are going to go ahead and type the properties of the JSON as follows:所以我们先到 go,然后键入 JSON 的属性,如下所示:

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[];
};

Basically what I said is we have bookdata which is made up of books, authors, and tags.基本上我所说的是我们有由书籍、作者和标签组成的书籍数据。 Books have properties given under type Book, same thing with Author and Tag.书籍在 Book 类型下具有属性,与 Author 和 Tag 相同。

Now for the actual running code, we are going to use the fetch api to get the json data at the url.现在对于实际运行的代码,我们将使用 fetch api 来获取 url 处的 json 数据。

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)));
}

First thing we do is fetch the data from the api, this returns a promise which when resolved (this is what.then does) we take the response and parse it for a json. Then when that promise resolves we get the books in the data.我们做的第一件事是从 api 中获取数据,这将返回一个 promise,当它被解析时(这就是然后所做的)我们获取响应并将其解析为 json。然后当 promise 解析时我们得到数据中的书籍. Then when that promise resolves we filter in books that have the matching tag.然后当 promise 解析时,我们过滤具有匹配标签的书籍。

doesBookHaveTag is just a little helper function I defined: doesBookHaveTag只是我定义的一个小帮手 function :

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

If you don't understand promises you should watch some videos on it, but basically the browser sends out an http request and then when it resolves it queues a task to execute the function [see endnote] in.then when it has time.如果你不理解 promises 你应该看一些关于它的视频,但基本上浏览器发出一个 http 请求,然后当它解析时它排队一个任务来执行 function [见尾注] in.then 有时间的时候。 So when we want to call your async function and say log all books with the tag "horror" we do it as shown:因此,当我们想调用您的异步 function 并说记录所有带有标签“恐怖”的书籍时,我们会按如下所示进行操作:

getBookTags("horror").then(console.log); // returns the one book.

I hope this makes sense and you can sort of see how to fetch the data, how to handle the promise it returns, and how to type your response.我希望这是有道理的,您可以了解如何获取数据、如何处理它返回的 promise 以及如何键入您的响应。 The only thing I'm not sure on is how Angular changes this for you (I'm a react guy), but this is really just non-library specific Javascript/Typescript.我唯一不确定的是 Angular 如何为您更改此设置(我是一个 React 人),但这实际上只是非库特定的 Javascript/Typescript。

[endnote] when I say function in.then, what I mean is that.then(data => data.books) is passing a function into the.then function. data => data.books is actually a function the same as: [尾注] 当我说 function in.then 时,我的意思是 .then(data => data.books) 将 function 传递给 the.then function。data => data.books 实际上是一个 function,与:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM