在flatter上解码来自Youtube api的Json

在flatter上解码来自Youtube api的Json,json,flutter,youtube-data-api,Json,Flutter,Youtube Data Api,我调用Youtube API并获得以下Json: "kind": "youtube#videoListResponse", "etag": "\"XI7nbFXulYBIpL0ayR_gDh3eu1k/s7-xmHXpuqQxYzDp_wxhm59K4LE\"", "pageInfo": { "totalResults": 1, "resultsPerPage": 1 }, "items": [ { "kind": "youtube#video", "e

我调用Youtube API并获得以下Json:

     "kind": "youtube#videoListResponse",
 "etag": "\"XI7nbFXulYBIpL0ayR_gDh3eu1k/s7-xmHXpuqQxYzDp_wxhm59K4LE\"",
 "pageInfo": {
  "totalResults": 1,
  "resultsPerPage": 1
 },
 "items": [
  {
   "kind": "youtube#video",
   "etag": "\"XI7nbFXulYBIpL0ayR_gDh3eu1k/pajQ7iBy-7A0V_owifxkw-Kbw-Y\"",
   "id": "7lCDEYXw3mM",
   "snippet": {
    "publishedAt": "2012-06-20T23:12:38.000Z",
    "channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw",
    "title": "Google I/O 101: Q&A On Using Google APIs",
    "description": "Antonio Fuentes speaks to us and takes questions on working with Google APIs and OAuth 2.0.",
    "thumbnails": {
     "default": {
      "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/default.jpg",
      "width": 120,
      "height": 90
     },
     "medium": {
      "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/mqdefault.jpg",
      "width": 320,
      "height": 180
     },
     "high": {
      "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/hqdefault.jpg",
      "width": 480,
      "height": 360
     }
但现在我想解析它,只得到3个节点:

  • 头衔
  • 描述
  • 默认缩略图的url
  • 事实上,我得到了Json响应,并且可以在日志中看到它,但是每次尝试解析它时都失败了

    这是我的代码:

    final response = await http.get(
        'https://www.googleapis.com/youtube/v3/videos?id=HEREGOESMYAPIKEY&part=snippet&id=T0Jqdjbed40');
    
    final parsed = json.decode(response.body).cast<Map<String, dynamic>>();
    String title  = parsed['items']['snippet']['title'];
    print(title);
    String description  = parsed['items']['snippet']['description'];
    print(description);
    String thumbnail  = parsed['items']['snippet']['thumbnails']['default']['url'];
    print(thumbnail);
    
    final response=wait http.get(
    'https://www.googleapis.com/youtube/v3/videos?id=HEREGOESMYAPIKEY&part=snippet&id=T0Jqdjbed40');
    final parsed=json.decode(response.body.cast();
    字符串标题=已解析的['items']['snippet']['title'];
    印刷品(标题);
    字符串描述=已解析的['items']['snippet']['description'];
    打印(说明);
    字符串缩略图=已解析的['items']['snippet']['thumbnails']['default']['url'];
    打印(缩略图);
    
    您正在尝试的东西无法使用Dart,这不是javascript。Dart有非常强大的类型系统,这很好。您正试图为定义为
    String
    的变量赋值,但您定义的响应是动态的,因此Dart无法验证赋值。另外items是数组,没有这样的key items->snippet

    正确的方法是创建模型定义,它将处理反序列化,并提供访问您感兴趣的属性的方便方法

    class YoutubeResponse {
    
      String kind;
      String etag;
      String nextPageToken;
    
      String regionCode;
      List<Item> items;
    
      YoutubeResponse(
          {this.kind,
          this.etag,
          this.nextPageToken,
          this.regionCode,
          this.items});
    
      Map<String, dynamic> toJson() => {
            'kind': kind,
            'etag': etag,
            'nextPageToken': nextPageToken,
            'regionCode': regionCode,
            'items': items,
          };
    
      factory YoutubeResponse.fromJSON(Map<String, dynamic> YoutubeResponseJson) {
    
        var list = YoutubeResponseJson['items'] as List;
        List<Item> itemsList = list.map((i) => Item.fromJSON(i)).toList();
    
        return new YoutubeResponse(
            kind: YoutubeResponseJson['kind'],
            etag: YoutubeResponseJson['etag'],
            nextPageToken: YoutubeResponseJson['nextPageToken'],
            regionCode: YoutubeResponseJson['regionCode'],
            mPageInfo: pageInfo.fromJSON(YoutubeResponseJson['pageInfo']),
            items: itemsList);
      }
    
    }
    
    class Item {
      String kind;
      String etag;
      Id id;
      Snippet snippet;
    
      Item({this.kind, this.etag, this.id, this.snippet});
    
      Map<String, dynamic> toJson() => {
            'kind': kind,
            'etag': etag,
            'id': id,
            'snippet': snippet,
          };
    
      factory Item.fromJSON(Map<String, dynamic> ItemJson) {
        return Item(
          kind: ItemJson['kind'],
          etag: ItemJson['etag'],
          id: Id.fromJSON(ItemJson['id']),
          snippet: Snippet.fromJSON(ItemJson['snippet']),
        );
      }
    }
    
    class Snippet {
      String publishedAt;
      String channelId;
      String title;
      String description;
      Thumbnails thumbnails;
      String channelTitle;
      String liveBroadcastContent;
    
      Snippet(
          {this.publishedAt,
          this.channelId,
          this.title,
          this.description,
          this.thumbnails,
          this.channelTitle,
          this.liveBroadcastContent});
    
    
      Map<String, dynamic> toJson() => {
            'publishedAt': publishedAt,
            'channelId': channelId,
            'title': title,
            'description': description,
            'thumbnails': thumbnails,
            'channelTitle': channelTitle,
            'liveBroadcastContent': liveBroadcastContent,
          };
    
      factory Snippet.fromJSON(Map<String, dynamic> SnippetJson) {
    
    
        return Snippet(
          publishedAt: SnippetJson['publishedAt'],
          channelId: SnippetJson['channelId'],
          title: SnippetJson['title'],
          description: SnippetJson['description'],
          thumbnails:  Thumbnails.fromJSON(SnippetJson['thumbnails']) ,
          channelTitle: SnippetJson['channelTitle'],
          liveBroadcastContent: SnippetJson['liveBroadcastContent'],
        );
      }
    }
    
    class Medium {
      int height;
      int width;
      String url;
    
      Medium({this.height, this.width, this.url});
    
      Map<String, dynamic> toJson() => {
            'height': height,
            'width': width,
            'url': url,
          };
    
      factory Medium.fromJSON(Map<String, dynamic> MediumJson) {
        return Medium(
          height: MediumJson['height'],
          width: MediumJson['width'],
          url: MediumJson['url'],
        );
      }
    
    }
    
    class High {
      int height;
      int width;
      String url;
    
      High({this.height, this.width, this.url});
    
      Map<String, dynamic> toJson() => {
            'height': height,
            'width': width,
            'url': url,
          };
    
      factory High.fromJSON(Map<String, dynamic> HighJson) {
        return High(
          height: HighJson['height'],
          width: HighJson['width'],
          url: HighJson['url'],
        );
      }
    
    }
    
    class Default {
      int height;
      int width;
      String url;
    
      Default({this.height, this.width, this.url});
    
      Map<String, dynamic> toJson() => {
            'height': height,
            'width': width,
            'url': url,
          };
    
      factory Default.fromJSON(Map<String, dynamic> defaultJson) {
        return Default(
          height: defaultJson['height'],
          width: defaultJson['width'],
          url: defaultJson['url'],
        );
      }
    
    }
    
    class Thumbnails {
      Default mDefault;
      Medium medium;
      High high;
    
      Thumbnails({this.mDefault, this.medium, this.high});
    
      var data = JsonEncoder().convert("");
    
      Map<String, dynamic> toJson() => {
            'default': mDefault,
            'medium': medium,
            'high': high,
          };
    
      factory Thumbnails.fromJSON(Map<String, dynamic> ThumbnailsJson) {
        return Thumbnails(
          mDefault: Default.fromJSON(ThumbnailsJson['default']),
          medium: Medium.fromJSON(ThumbnailsJson['medium']),
          high: High.fromJSON(ThumbnailsJson['high']),
        );
      }
    }
    

    然后,您可以通过
    parsedResponse.items
    访问这些项目,然后循环浏览它们,并获取标题、描述等。

    通过@Shaddy进一步了解答案(它可以工作)。这里是我调用网络的类

        class VideoNetwork {
      static Future<List<Item>> fetchPost() async {
        final response =
            await http.get(<URL for Youtube Videos>);
    
        if (response.statusCode == 200) {
          // If the call to the server was successful, parse the JSON
          return compute(parseVideos, response.body);
        } else {
          // If that call was not successful, throw an error.
          throw Exception('Failed to load post');
        }
      }
    
      static List<Item> parseVideos(String responseBody) {
        YoutubeResponse response =
            YoutubeResponse.fromJSON(json.decode(responseBody));
    
        return response.items.toList();
      }
    }
    
    class视频网络{
    静态未来fetchPost()异步{
    最后答复=
    等待http.get();
    如果(response.statusCode==200){
    //如果对服务器的调用成功,则解析JSON
    返回compute(parseVideos,response.body);
    }否则{
    //如果该调用未成功,则抛出一个错误。
    抛出异常(“加载post失败”);
    }
    }
    静态列表解析视频(字符串响应库){
    YouTube响应=
    YoutubeResponse.fromJSON(json.decode(responseBody));
    返回response.items.toList();
    }
    }
    
    回答这个问题可能有点晚了

    如果您想了解如何解析复杂的json数据,请使用以下文章

    仅供参考-Youtube数据api响应采用嵌套Json格式

    我使用了另一种方法,这不建议用于大型应用程序(我只是在玩弄它,这只适用于上述类型的json树)

    使用异步函数检索和解析Json数据

    final String dataUrl = "YOUR-JSON-URL";
    
    Future<String> getdet() async {
    
    var response = await http.get(Uri.encodeFull(dataUrl), headers: {"Accept": "application/json"});
    
        if (response.statusCode == 200) {
          var responseBody = json.decode(response.body);
    
          convertedData = responseBody["items"];
    
        } else {
          throw Exception('Failed to Load Data');
        }
    
    final String dataUrl=“YOUR-JSON-URL”;
    Future getdet()异步{
    var response=wait http.get(Uri.encodeFull(dataUrl),头:{“Accept”:“application/json”});
    如果(response.statusCode==200){
    var responseBody=json.decode(response.body);
    convertedData=ResponseBy[“items”];
    }否则{
    抛出异常(“加载数据失败”);
    }
    
    “items”是数组的起点

    之后,您可以在小部件中使用它

    Widget recentWidget(){
        return ListView.builder(
                  itemCount: convertedData == null ? 0 : recent.length,
                  itemBuilder: (BuildContext context, int index, ) {
                  return Column(
                   children: <Widget>[
                      Card(
                        child: Column(
                          children: <Widget>[
                            new Image.network(recent[index]["snippet"]["thumbnails"]["medium"]["url"]),
                            new ListTile(                         
                                title: new Text(recent[index]["snippet"]["title"]),
                                    subtitle: Text("This is Subtitle"),
                                 },
                                dense: true,
                              ),
                          ],
                      ),
                  )
                ],
              );
            },shrinkWrap: true,
            physics: ClampingScrollPhysics(),
          )
        }
    
    Widget-recentWidget(){
    返回ListView.builder(
    itemCount:convertedData==null?0:recent.length,
    itemBuilder:(BuildContext上下文,int索引,){
    返回列(
    儿童:[
    卡片(
    子:列(
    儿童:[
    新的图像。网络(最近的[索引][“代码段”][“缩略图”][“中等”][“url”]),
    新名单(
    标题:新文本(最近的[索引][“代码段][“标题]),
    字幕:文本(“这是字幕”),
    },
    是的,
    ),
    ],
    ),
    )
    ],
    );
    },覆膜收缩膜:正确,
    物理:ClampingScrollPhysics(),
    )
    }
    

    希望这能有所帮助。

    对@Sh1d0w的回答很好,但对于那些不太了解flatter本身的人来说,它缺乏内容。我必须说谢谢Sh1d0w,因为你给了我创建自己代码的基础,以便使用youtube url获取数据

    我使用SearchDelegate组合了他的答案,为了显示结果,我仍然需要添加代码来显示下一页/上一页的结果(youtube每页只提供50个结果),但要回答您的问题,这里是代码。 最后,您将能够获得以下信息:

    出版 渠道 标题 描述 缩略图(默认、高、中) 直播内容 视频ID

    如果需要json中的任何其他数据,则需要在类片段中添加所需内容,以便稍后返回和使用。 由于我使用的futureBuilder提供snapshot.data对象中的数据,因此需要使用这种声明来获取每个属性:

    snapshot.data[index].title
    snapshot.data[index].description
    snapshot.data[index].thumbnails.high.url
    
    
    **在代码中,您将看到appTheme.text等内容,这些只是颜色的变量,请为您的颜色更改它们。 **sizeBuild()或fontSizeBuild()之类的函数是我为我的案例创建的函数,您只需删除这些行并根据需要写入任意数字

    普通飞镖

    import 'dart:convert';
    
    class YoutubeResponse{
      //!-1st level parameters of youtube api for playlist
      //!-https://developers.google.com/youtube/v3/docs/playlistItems/list#response
      String kind;
      String etag;
      String nextPageToken;
      String prevPageToken;
      String regionCode;
      List<Item> items;
      //change the default values for the obtained values from url
      YoutubeResponse({
        this.kind,
        this.etag,
        this.nextPageToken,
        this.prevPageToken,
        this.regionCode,
        this.items
      });
      //Json decode and make a dart object called Map
      Map<String, dynamic> toJson() => {
        'kind': kind,
        'etag': etag,
        'nextPageToken': nextPageToken,
        'prevPageToken': prevPageToken,
        'regionCode': regionCode,
        'items': items,
      };
    
      factory YoutubeResponse.fromJSON(Map<String, dynamic> YoutubeResponseJson){
        var list = YoutubeResponseJson['items'] as List;
        List<Item> itemsList = list.map((i)=> Item.fromJSON(i)).toList();
        return new YoutubeResponse(
          kind: YoutubeResponseJson['kind'],
          etag: YoutubeResponseJson['etag'],
          nextPageToken: YoutubeResponseJson['nextPageToken'],
          prevPageToken: YoutubeResponseJson['prevPageToken'],
          regionCode: YoutubeResponseJson['regionCode'],
          // mPageInfo: pageInfo.fromJSON(YoutubeResponseJson['pageInfo']),
          items: itemsList
        );
      }
    }
    
    //---------Create an single video item
    
    class Item{
      String kind;
      String etag;
      String id;
      Snippet snippet;
    
      Item({
        this.kind, this.etag, this.id, this.snippet
      });
    
      Map<String, dynamic> toJson() => {
        'kind': kind,
        'etag': etag,
        'id': id,
        'snippet': snippet,
      };
      
      factory Item.fromJSON(Map<String, dynamic> ItemJson) {
        return Item(
          kind: ItemJson['kind'],
          etag: ItemJson['etag'],
          id: ItemJson['id'],
          snippet: Snippet.fromJSON(ItemJson['snippet']),
        );
      }
    
    }
    
    class Snippet {
      String publishedAt;
      String channelId;
      String title;
      String description;
      Thumbnails thumbnails;
      String channelTitle;
      String liveBroadcastContent;
      String videoId;
    
      Snippet(
          {this.publishedAt,
          this.channelId,
          this.title,
          this.description,
          this.thumbnails,
          this.channelTitle,
          this.liveBroadcastContent,
          this.videoId,
          });
    
    
      Map<String, dynamic> toJson() => {
            'publishedAt': publishedAt,
            'channelId': channelId,
            'title': title,
            'description': description,
            'thumbnails': thumbnails,
            'channelTitle': channelTitle,
            'liveBroadcastContent': liveBroadcastContent,
            'videoId': videoId,
          };
    
      factory Snippet.fromJSON(Map<String, dynamic> snippetJson) {
    
    
        return Snippet(
          publishedAt: snippetJson['publishedAt'],
          channelId: snippetJson['channelId'],
          title: snippetJson['title'],
          description: snippetJson['description'],
          thumbnails:  Thumbnails.fromJSON(snippetJson['thumbnails']) ,
          channelTitle: snippetJson['channelTitle'],
          liveBroadcastContent: snippetJson['liveBroadcastContent'],
          videoId: snippetJson['resourceId']['videoId'],
        );
      }
    }
    
    class Medium {
      int height;
      int width;
      String url;
    
      Medium({this.height, this.width, this.url});
    
      Map<String, dynamic> toJson() => {
            'height': height,
            'width': width,
            'url': url,
          };
    
      factory Medium.fromJSON(Map<String, dynamic> MediumJson) {
        return Medium(
          height: MediumJson['height'],
          width: MediumJson['width'],
          url: MediumJson['url'],
        );
      }
    
    }
    
    class High {
      int height;
      int width;
      String url;
    
      High({this.height, this.width, this.url});
    
      Map<String, dynamic> toJson() => {
            'height': height,
            'width': width,
            'url': url,
          };
    
      factory High.fromJSON(Map<String, dynamic> HighJson) {
        return High(
          height: HighJson['height'],
          width: HighJson['width'],
          url: HighJson['url'],
        );
      }
    
    }
    
    class Default {
      int height;
      int width;
      String url;
    
      Default({this.height, this.width, this.url});
    
      Map<String, dynamic> toJson() => {
            'height': height,
            'width': width,
            'url': url,
          };
    
      factory Default.fromJSON(Map<String, dynamic> defaultJson) {
        return Default(
          height: defaultJson['height'],
          width: defaultJson['width'],
          url: defaultJson['url'],
        );
      }
    
    }
    
    class Thumbnails {
      Default mDefault;
      Medium medium;
      High high;
    
      Thumbnails({this.mDefault, this.medium, this.high});
      
      var data = JsonEncoder().convert("");
    
      Map<String, dynamic> toJson() => {
            'default': mDefault,
            'medium': medium,
            'high': high,
          };
    
    
      factory Thumbnails.fromJSON(Map<String, dynamic> thumbnailsJson) {
        return Thumbnails(
          mDefault: Default.fromJSON(thumbnailsJson['default']),
          medium: Medium.fromJSON(thumbnailsJson['medium']),
          high: High.fromJSON(thumbnailsJson['high']),
        );
      }
    }
    
    
    
    
    
    类数据搜索扩展了SearchDelegate{
    var nextPageToken;
    var-prevPageToken;
    未来(Future)推出,;
    //ajax/http数据请求
    未来的getVideos(http.Client)异步{
    YouTube响应解析响应;
    最终响应=等待客户
    .get('https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=$youtubeTrickPlaylist&key=$youtubeAPIKEY&maxResults=50’;
    列出视频=[];
    parsedResponse=YoutubeResponse.fromJSON(json.decode(response.body));
    for(var i=0;iimport 'dart:convert';
    
    class YoutubeResponse{
      //!-1st level parameters of youtube api for playlist
      //!-https://developers.google.com/youtube/v3/docs/playlistItems/list#response
      String kind;
      String etag;
      String nextPageToken;
      String prevPageToken;
      String regionCode;
      List<Item> items;
      //change the default values for the obtained values from url
      YoutubeResponse({
        this.kind,
        this.etag,
        this.nextPageToken,
        this.prevPageToken,
        this.regionCode,
        this.items
      });
      //Json decode and make a dart object called Map
      Map<String, dynamic> toJson() => {
        'kind': kind,
        'etag': etag,
        'nextPageToken': nextPageToken,
        'prevPageToken': prevPageToken,
        'regionCode': regionCode,
        'items': items,
      };
    
      factory YoutubeResponse.fromJSON(Map<String, dynamic> YoutubeResponseJson){
        var list = YoutubeResponseJson['items'] as List;
        List<Item> itemsList = list.map((i)=> Item.fromJSON(i)).toList();
        return new YoutubeResponse(
          kind: YoutubeResponseJson['kind'],
          etag: YoutubeResponseJson['etag'],
          nextPageToken: YoutubeResponseJson['nextPageToken'],
          prevPageToken: YoutubeResponseJson['prevPageToken'],
          regionCode: YoutubeResponseJson['regionCode'],
          // mPageInfo: pageInfo.fromJSON(YoutubeResponseJson['pageInfo']),
          items: itemsList
        );
      }
    }
    
    //---------Create an single video item
    
    class Item{
      String kind;
      String etag;
      String id;
      Snippet snippet;
    
      Item({
        this.kind, this.etag, this.id, this.snippet
      });
    
      Map<String, dynamic> toJson() => {
        'kind': kind,
        'etag': etag,
        'id': id,
        'snippet': snippet,
      };
      
      factory Item.fromJSON(Map<String, dynamic> ItemJson) {
        return Item(
          kind: ItemJson['kind'],
          etag: ItemJson['etag'],
          id: ItemJson['id'],
          snippet: Snippet.fromJSON(ItemJson['snippet']),
        );
      }
    
    }
    
    class Snippet {
      String publishedAt;
      String channelId;
      String title;
      String description;
      Thumbnails thumbnails;
      String channelTitle;
      String liveBroadcastContent;
      String videoId;
    
      Snippet(
          {this.publishedAt,
          this.channelId,
          this.title,
          this.description,
          this.thumbnails,
          this.channelTitle,
          this.liveBroadcastContent,
          this.videoId,
          });
    
    
      Map<String, dynamic> toJson() => {
            'publishedAt': publishedAt,
            'channelId': channelId,
            'title': title,
            'description': description,
            'thumbnails': thumbnails,
            'channelTitle': channelTitle,
            'liveBroadcastContent': liveBroadcastContent,
            'videoId': videoId,
          };
    
      factory Snippet.fromJSON(Map<String, dynamic> snippetJson) {
    
    
        return Snippet(
          publishedAt: snippetJson['publishedAt'],
          channelId: snippetJson['channelId'],
          title: snippetJson['title'],
          description: snippetJson['description'],
          thumbnails:  Thumbnails.fromJSON(snippetJson['thumbnails']) ,
          channelTitle: snippetJson['channelTitle'],
          liveBroadcastContent: snippetJson['liveBroadcastContent'],
          videoId: snippetJson['resourceId']['videoId'],
        );
      }
    }
    
    class Medium {
      int height;
      int width;
      String url;
    
      Medium({this.height, this.width, this.url});
    
      Map<String, dynamic> toJson() => {
            'height': height,
            'width': width,
            'url': url,
          };
    
      factory Medium.fromJSON(Map<String, dynamic> MediumJson) {
        return Medium(
          height: MediumJson['height'],
          width: MediumJson['width'],
          url: MediumJson['url'],
        );
      }
    
    }
    
    class High {
      int height;
      int width;
      String url;
    
      High({this.height, this.width, this.url});
    
      Map<String, dynamic> toJson() => {
            'height': height,
            'width': width,
            'url': url,
          };
    
      factory High.fromJSON(Map<String, dynamic> HighJson) {
        return High(
          height: HighJson['height'],
          width: HighJson['width'],
          url: HighJson['url'],
        );
      }
    
    }
    
    class Default {
      int height;
      int width;
      String url;
    
      Default({this.height, this.width, this.url});
    
      Map<String, dynamic> toJson() => {
            'height': height,
            'width': width,
            'url': url,
          };
    
      factory Default.fromJSON(Map<String, dynamic> defaultJson) {
        return Default(
          height: defaultJson['height'],
          width: defaultJson['width'],
          url: defaultJson['url'],
        );
      }
    
    }
    
    class Thumbnails {
      Default mDefault;
      Medium medium;
      High high;
    
      Thumbnails({this.mDefault, this.medium, this.high});
      
      var data = JsonEncoder().convert("");
    
      Map<String, dynamic> toJson() => {
            'default': mDefault,
            'medium': medium,
            'high': high,
          };
    
    
      factory Thumbnails.fromJSON(Map<String, dynamic> thumbnailsJson) {
        return Thumbnails(
          mDefault: Default.fromJSON(thumbnailsJson['default']),
          medium: Medium.fromJSON(thumbnailsJson['medium']),
          high: High.fromJSON(thumbnailsJson['high']),
        );
      }
    }
    
    
    
    
    
    import 'package:flutter/material.dart';
    import 'dart:async';
    import 'dart:convert';
    import 'package:http/http.dart' as http;
    import 'package:denApp/keys/app_keys.dart'; //put your keys always in a different file with gitignore
    import 'package:url_launcher/url_launcher.dart'; //for links in each item
    import 'package:denApp/Widgets/common_youtubeAPI.dart'; //here are the models of each data requested in the json to be used here
    
    
    class DataSearch extends SearchDelegate<List>{
      var nextPageToken;
      var prevPageToken;
      Future<void> _launched;
        //ajax/http request for data
        Future<List<Snippet>> getVideos(http.Client client) async {
          YoutubeResponse parsedResponse;
          final response = await client
              .get('https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&playlistId=$youtubeTrickPlaylist&key=$youtubeAPIKEY&maxResults=50');
          List<Snippet> videos = [];
          parsedResponse = YoutubeResponse.fromJSON(json.decode(response.body));
          for(var i=0; i < parsedResponse.items.length; i++ ){
            videos.add(parsedResponse.items[i].snippet);
          }
          this.nextPageToken = parsedResponse.nextPageToken;
          this.prevPageToken = parsedResponse.prevPageToken;
          print(this.nextPageToken);
          print(this.prevPageToken);
          return videos;
      }
      //We use the launcher plugin to manage the click to go to the website, please visit the plugin web for info how to use it
    
      Future<void> _launchInBrowser(String url) async {
        print(url);
        if (await canLaunch(url)) {
          await launch(
            url,
            forceSafariVC: false,
            forceWebView: false,
            headers: <String, String>{'my_header_key': 'my_header_value'},
          );
        } else {
          throw 'Could not launch $url';
        }
      }
    
    //------------------------------------------------------
    //--This part is to edit the colors and design of the searchDelegate widget, I have a separated file with the themes, colors which I call using appTheme, so you need to change all those variables with your own colors.
    
      @override
      ThemeData appBarTheme(BuildContext context) {
          return ThemeData(
            primaryColor: appTheme.text,
            backgroundColor: appTheme.dark,
            bottomAppBarColor: appTheme.dark,
            canvasColor: appTheme.dark,
    
          );
      }
    
    //-------------------------------------------------------------
    //---Here we define how it will works the SearchDelegate and its icons/functions-----------
    
      @override
      List<Widget> buildActions(BuildContext context) {
          // ----This is the icon which will delete whatever you write in your searchbar
          return [IconButton(icon: Icon(Icons.clear), onPressed: () {
            query="";
          },)];
        }
      
        @override
        Widget buildLeading(BuildContext context) {
          // ---- This is the icon which will allow you to close the search delegate going to the back page.
          return IconButton(icon: Icon(Icons.arrow_back), onPressed: (){
            close(context, null);
          });
        }
      
        @override
        Widget buildResults(BuildContext context) {
          // nothing here
          throw UnimplementedError();
        }
      
        @override
        Widget buildSuggestions(BuildContext context) {
        // This is actually the place where you will do all the work when you receive the data from your future request. Since we are going to build something after we wait for the data, we need to use futureBuilder instead of builder only. In the future propiety you will put the function which will do the request to the api  
        return FutureBuilder<List<Snippet>>(
          future: getVideos(http.Client()),
          builder: (context, snapshot) {
            //during the build you need to check the connection state so depending on what is happening you will show something , like a loader if it is waiting state, etc
            switch (snapshot.connectionState){
              case ConnectionState.none:
                return Text('none', style: TextStyle(color:Colors.black));
              case ConnectionState.active:
                return Text('active', style: TextStyle(color:Colors.black));
              case ConnectionState.waiting:
                return Center(
                  child: CircularProgressIndicator(),
                );
              default:
      
                //after checking connection we need to check if we do not got null data from the request
                if(snapshot.data != null){
                  var dt = snapshot.data.where((p)=> p.title.toLowerCase().contains(query.toLowerCase())).toList();
                  return dt.isEmpty? Center(child:Text("There was no results for your query", style: TextStyle(color: appTheme.text))) : ListView.builder(
    
                      itemCount: dt.length,
                      padding: EdgeInsets.zero,
                      itemBuilder: (context, index) {
                        if(query.isEmpty){
                          return Card(
                            margin: (index == (dt.length - 1)) ? EdgeInsets.only(top: sizeBuild(context, "height", 5), bottom: sizeBuild(context, "height", 15)) : EdgeInsets.only(top: sizeBuild(context, "height", 5)),
                            color: appTheme.bgLight.withOpacity(.1),
                            child: InkWell(
                              splashColor: appTheme.linkB.withAlpha(30),
                              onTap: () {
                                _launched = _launchInBrowser('https://www.youtube.com/watch?v=${snapshot.data[index].videoId}');
                              },
                              child: Container(
                                child: Row(
                                  children: <Widget>[
                                    Container(
                                      width:sizeBuild(context, "width", 140),
                                      child: Image.network("${snapshot.data[index].thumbnails.high.url}", fit: BoxFit.cover),
                                    ),
                                    Container(
                                      // color: Colors.red,
                                      margin: EdgeInsets.symmetric(horizontal: sizeBuild(context, "width",10)),
                                      width:sizeBuild(context, "width", 280),
                                      child: Column(
                                      crossAxisAlignment: CrossAxisAlignment.start,
                                      children: <Widget>[
                                        Text(snapshot.data[index].title,
                                          maxLines: 1,
                                          overflow: TextOverflow.ellipsis,
                                          style: TextStyle (
                                              color: appTheme.text,
                                              fontWeight: FontWeight.bold,
                                              fontSize: fontSizeBuild(context, 'body')
                                          ),
                                        ),
                                        SizedBox(
                                          height: sizeBuild(context, "height", 5),
                                        ),
                                        Text(snapshot.data[index].description,
                                          maxLines: 3,
                                          overflow: TextOverflow.ellipsis,
                                          style: TextStyle (
                                              color: appTheme.text.withOpacity(.7),
                                              fontSize: fontSizeBuild(context, 'small')
                                          ),
                                        ),
                                      
                                      ],
                                    ),
                                    ),
                                  ],
                                ),
                              ),
                            ),
                          );
                        }else{
                          return Card(
                            margin: (index == (dt.length - 1)) ? EdgeInsets.only(top: sizeBuild(context, "height", 5), bottom: sizeBuild(context, "height", 15)) : EdgeInsets.only(top: sizeBuild(context, "height", 5)),
                            color: appTheme.bgLight.withOpacity(.1),
                            child: InkWell(
                              splashColor: appTheme.linkB.withAlpha(30),
                              onTap: () {
                                _launched = _launchInBrowser('https://www.youtube.com/watch?v=${snapshot.data[index].videoId}');
                              },
                              child: Container(
                                child: Row(
                                  children: <Widget>[
                                    Container(
                                      width:sizeBuild(context, "width", 140),
                                      child: Image.network("${snapshot.data[index].thumbnails.high.url}", fit: BoxFit.cover),
                                    ),
                                    Container(
                                      margin: EdgeInsets.symmetric(horizontal: sizeBuild(context, "width",10)),
                                      width:sizeBuild(context, "width", 280),
                                      child: Column(
                                      crossAxisAlignment: CrossAxisAlignment.start,
                                      children: <Widget>[
                                        Text(snapshot.data[index].title,
                                          maxLines: 1,
                                          overflow: TextOverflow.ellipsis,
                                          style: TextStyle (
                                              color: appTheme.text,
                                              fontWeight: FontWeight.bold,
                                              fontSize: fontSizeBuild(context, 'body')
                                          ),
                                        ),
                                        SizedBox(
                                          height: sizeBuild(context, "height", 20),
                                        ),
                                        Text(snapshot.data[index].description,
                                          maxLines: 5,
                                          overflow: TextOverflow.ellipsis,
                                          style: TextStyle (
                                              color: appTheme.text.withOpacity(.7),
                                              fontSize: fontSizeBuild(context, 'small')
                                          ),
                                        ),
                                      
                                      ],
                                    ),
                                    ),
                                  ],
                                ),
                              ),
                            ),
                          );
                        }
                      },
                     
                    );
                }else{
                  //this is the widget to give if there is no data
                  return Center(child: Text("There was no data from the server", style: TextStyle(color:appTheme.text)));
                }
            }
          },
        );
      }
    
    }
    
    import 'dart:convert';
    
    void main() {
      final parsed = jsonDecode(responseBody);
      String title  = parsed['items'][0]['snippet']['title'];
      String description  = parsed['items'][0]['snippet']['description'];
      String thumbnail  = parsed['items'][0]['snippet']['thumbnails']['default']['url'];
      print('title: $title');
      print('description: $description');
      print('thumbnail: $thumbnail');
    }
    
    const responseBody = '''{
      "kind": "youtube#videoListResponse",
      "etag": "\\\"XI7nbFXulYBIpL0ayR_gDh3eu1k/s7-xmHXpuqQxYzDp_wxhm59K4LE\\\"",
      "pageInfo": {
        "totalResults": 1,
        "resultsPerPage": 1
      },
      "items": [
        {
          "kind": "youtube#video",
          "etag": "\\\"XI7nbFXulYBIpL0ayR_gDh3eu1k/pajQ7iBy-7A0V_owifxkw-Kbw-Y\\\"",
          "id": "7lCDEYXw3mM",
          "snippet": {
            "publishedAt": "2012-06-20T23:12:38.000Z",
            "channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw",
            "title": "Google I/O 101: Q&A On Using Google APIs",
            "description": "Antonio Fuentes speaks to us and takes questions on working with Google APIs and OAuth 2.0.",
            "thumbnails": {
              "default": {
                "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/default.jpg",
                "width": 120,
                "height": 90
              },
              "medium": {
                "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/mqdefault.jpg",
                "width": 320,
                "height": 180
              },
              "high": {
                "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/hqdefault.jpg",
                "width": 480,
                "height": 360
              }
            }
          }
        }
      ]
    }''';