Не удается получить данные nytimes для раздела технологии с помощью их официального API

#flutter #api #web-services #dart #webservice-client

Вопрос:

Я пытаюсь использовать API для извлечения NYTimes и технология новости секции и используя на моем веб-приложение, но _articles.length это бросает меня ошибка noSuchMethodError Я попытался запустить его с занятиями спортом и других разделов его работы, но он бросает ошибку для технологии разделе и я только хочу, что для моего проекта, и я также пробовал URL-адрес на почтальона он отлично работает для технологии есть, но не в флаттер и Дарт пожалуйста, помогите,

Я получаю ошибку ниже в консоли vscode для использования раздела технологии,

 Error: NoSuchMethodError: 'length'
method not found
Receiver: null
Arguments: []
    at Object.throw_ [as throw] (http://localhost:60362/dart_sdk.js:5061:11)
    at api_service.APIService.new.fetchArticlesBySection (http://localhost:60362/packages/devcom/services/api_service.dart.lib.js:43:23)
    at fetchArticlesBySection.next (<anonymous>)
    at http://localhost:60362/dart_sdk.js:38640:33
    at _RootZone.runUnary (http://localhost:60362/dart_sdk.js:38511:59)
    at _FutureListener.thenAwait.handleValue (http://localhost:60362/dart_sdk.js:33713:29)
    at handleValueCallback (http://localhost:60362/dart_sdk.js:34265:49)
    at Function._propagateToListeners (http://localhost:60362/dart_sdk.js:34303:17)
    at _Future.new.[_completeWithValue] (http://localhost:60362/dart_sdk.js:34151:23)
    at async._AsyncCallbackEntry.new.callback (http://localhost:60362/dart_sdk.js:34172:35)
    at Object._microtaskLoop (http://localhost:60362/dart_sdk.js:38778:13)
    at _startMicrotaskLoop (http://localhost:60362/dart_sdk.js:38784:13)
    at http://localhost:60362/dart_sdk.js:34519:9
 

Я не знаю, почему он выдает эту нулевую ошибку
, это мой файл dart, в котором я использовал функцию длины в последних строках кода, проверьте ниже

 import 'package:devcom/models/article_model.dart';
import 'package:devcom/services/api_service.dart';
import 'package:flutter/material.dart';
import 'package:devcom/utils/responsive.dart';
import 'package:url_launcher/url_launcher.dart';

class ExploreSection extends StatefulWidget {
  @override
  _ExploreSectionState createState() => _ExploreSectionState();
}

class _ExploreSectionState extends State<ExploreSection> {
  List<Article> _articles = [];

  @override
  void initState() {
    super.initState();
    _fetchArticles();
  }

  _fetchArticles() async {
    List<Article> articles =
        await APIService().fetchArticlesBySection("technology");
    setState(() {
      _articles = articles;
    });
  }

  _buildArticlesGrid(MediaQueryData mediaQuery) {
    List<GridTile> tiles = [];
    _articles.forEach((article) {
      tiles.add(_buildArticleTile(article, mediaQuery));
    });
    return Padding(
      padding: responsivePadding(mediaQuery),
      child: GridView.count(
        crossAxisCount: responsiveNumGridTiles(mediaQuery),
        mainAxisSpacing: 30.0,
        crossAxisSpacing: 30.0,
        shrinkWrap: true,
        physics: NeverScrollableScrollPhysics(),
        children: tiles,
      ),
    );
  }

  _launchURL(String url) async {
    if (await canLaunch(url)) {
      await launch(url);
    } else {
      throw 'Could not launch $url';
    }
  }

  _buildArticleTile(Article article, MediaQueryData mediaQuery) {
    return GridTile(
      child: GestureDetector(
        onTap: () => _launchURL(article.url),
        child: Column(
          children: <Widget>[
            Container(
              height: responsiveImageHeight(mediaQuery),
              alignment: Alignment.bottomCenter,
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(20.0),
                  topRight: Radius.circular(20.0),
                ),
                image: DecorationImage(
                  image: NetworkImage(article.imageUrl),
                  fit: BoxFit.cover,
                ),
              ),
            ),
            Container(
              padding: EdgeInsets.all(10.0),
              alignment: Alignment.center,
              height: responsiveTitleHeight(mediaQuery),
              width: double.infinity,
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.only(
                  bottomLeft: Radius.circular(20.0),
                  bottomRight: Radius.circular(20.0),
                ),
                boxShadow: [
                  BoxShadow(
                    color: Colors.black12,
                    offset: Offset(0, 1),
                    blurRadius: 6.0,
                  ),
                ],
              ),
              child: Text(
                article.title,
                textAlign: TextAlign.center,
                style: TextStyle(
                  fontSize: 20.0,
                  fontWeight: FontWeight.bold,
                ),
                maxLines: 2,
              ),
            ),
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final mediaQuery = MediaQuery.of(context);
    return Scaffold(
      body: ListView(
        children: <Widget>[
          SizedBox(height: 80.0),
          Center(
            child: Text(
              'The New York TimesnTop Tech Articles',
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 30.0,
                fontWeight: FontWeight.bold,
                letterSpacing: 1.5,
              ),
            ),
          ),
          SizedBox(height: 15.0),
          if (_articles.length > 0)         // the error causing line is this ig 
            _buildArticlesGrid(mediaQuery)
          else
            Center(
              child: CircularProgressIndicator(),
            ),
        ],
      ),
    );
  }
}
 

This is my api_service.dart :

 import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:devcom/models/article_model.dart';

class APIService {
  final String _baseUrl = 'api.nytimes.com';
  static const String API_KEY = 'MY_API_KEY_HERE';

  Future<List<Article>> fetchArticlesBySection(String section) async {
    Map<String, String> parameters = {
      'api-key': API_KEY,
    };
    Uri uri = Uri.https(
      _baseUrl,
      "/svc/topstories/v2/$section.json",
      parameters,
    );
    try {
      var response = await http.get(uri);
      Map<String, dynamic> data = json.decode(response.body);
      List<Article> articles = [];
      data['results'].forEach(
        (articleMap) => articles.add(Article.fromMap(articleMap)),
      );
      return articles;
    } catch (err) {
      throw err.toString();
    }
  }
}
 

В приведенном выше коде только CirclularProgressIndicator() выполняется независимо от условия.
Я следил за этим уроком из источника youtube

Это мой файл класса модели статьи dart:

 class Article {
  final String title;
  final String byline;
  final String url;
  final String imageUrl;
  final String publishedDate;
  final String summary;

  Article({
    required this.title,
    required this.byline,
    required this.url,
    required this.imageUrl,
    required this.publishedDate,
    required this.summary,
  });

  factory Article.fromMap(Map<String, dynamic> map) {
    return Article(
      title: map['title'],
      byline: map['byline'],
      url: map['url'],
      imageUrl: map['multimedia'].length > 0
          ? map['multimedia'][3]['url']
          : 'https://images.unsplash.com/photo-1504711434969-e33886168f5c?ixlib=rb-1.2.1amp;ixid=eyJhcHBfaWQiOjEyMDd9amp;auto=formatamp;fit=cropamp;w=1350amp;q=80',
      publishedDate: map['published_date'],
      summary: map['abstract'],
    );
  }
}
 

Комментарии:

1. можете ли вы напечатать длину в консоли?

2. @AmitSingh OP получит точно такую же ошибку.

3. @AmitSingh сначала я попытался напечатать _articles.length в scaffold, он выдает > Это выражение имеет тип «пустота», поэтому его значение нельзя использовать. Попробуйте проверить, используете ли вы правильный API; может быть функция или вызов, которые возвращают пустоту, которую вы не ожидали. Также проверьте параметры типа и переменные, которые также могут быть недействительными. поэтому я попытался использовать печать outside scaffold и в buildcontext , но это тоже ничего не печатает, ничего другого, что я должен попробовать

Ответ №1:

Это, скорее всего, вызывает вашу ошибку:

  List<Article> articles =
        await APIService().fetchArticlesBySection("technology");
 

Убедитесь, что он не равен нулю. Ошибка, которую вы получаете, возникает всякий раз, когда вы вызываете операциюметод в списке, например foreach, потому что dart сначала проверяет его длину, и если список равен нулю, вы получаете свою ошибку.

однако это должно решить вашу проблему, проверив, является ли она нулевой или нет, перед вызовом.длина:

 if(_articles != null) 
    _articles.length > 0 
       ?  _buildArticlesGrid(mediaQuery)
       :  Center(
       child: CircularProgressIndicator(),),

 

Комментарии:

1. Я попытался использовать ваш код, который показывает мне, что операнд не может быть равен нулю, поэтому условие всегда верно. Удалите это условие. но это ничего не меняет, это просто показывает, как обычно, циркулярный индикатор, любое другое решение, сэр,

2. Если вы получаете круговой индикатор, это означает, что ваша ошибка исчезла. И что твой список пуст.

3. Убедитесь, что ваш список не пуст.

4. Да, теперь он работает, спасибо, я проверил его, используя другой раздел, а не технологию

5. эй, но я не могу работать с разделом технологий, это не просто поиск, в чем проблема, можете ли вы помочь с этим другим разделом, просто отлично работает, я пробовал использовать раздел спорта и искусств. На самом деле моим главным девизом использования этого api nytimes было получение новостей из раздела технологий, но это только не работает, пожалуйста, помогите