Home > front end >  How can I fetch images from api into card widget in flutter?
How can I fetch images from api into card widget in flutter?

Time:04-14

I'm trying to fetch api images into the card widgets in flutter. I have services, model and photos_page class. I tried lot's of ways but still doesn't work.

final photoItem = snapshot.data[index].previewURL;

I think problem is that snapshot can't get data

that's my photos_page:

import 'dart:convert';

import 'package:abcde/services/photos_model.dart';
import 'package:abcde/services/photos_service.dart';
import 'package:abcde/widgets/card_widget.dart';
import 'package:flutter/material.dart';

class PhotosPage extends StatefulWidget {
   PhotosPage({Key? key}) : super(key: key);
  static const String pathId = 'Photos page';

  @override
  State<PhotosPage> createState() => _PhotosPageState();
}

class _PhotosPageState extends State<PhotosPage> {
  PhotosService photosService = PhotosService();
  @override
  void initState() {
    // TODO: implement initState
    super.initState();

photosService.getPhotos();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Photos'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(children: [
          _getProductTypeList(),
        ]),
      ),
    );
  }

  Widget _buildListItem(
      BuildContext context, AsyncSnapshot<dynamic> snapshot, int index) {
    final photoItem = snapshot.data[index].previewURL;
    print('photoItem is $photoItem');
    return photoCard(photoItem);
  }

  Widget _buildList(BuildContext context, AsyncSnapshot<dynamic> snapshot) {
    var values = snapshot.data;
    return ListView.builder(
    //  itemCount: snapshot.length,
      itemBuilder: (context, index) {
        return _buildListItem(context, snapshot, index);
      },
    );
/*    return ListView(
      children: snapshot!.map((data) => _buildListItem(context, data)).toList(),
    );*/
  }

//PhotosModel photosModel = PhotosModel();

  Widget _getProductTypeList() {
    return Expanded(
      child: FutureBuilder(
        future: photosService.getPhotos(),
        builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(
              child: LinearProgressIndicator(),
            );
          }
          return _buildList(context, snapshot);
        },
      ),
    );
  }
}

that's my model class:

class PhotosModel {
  String previewURL;

  PhotosModel({required this.previewURL});

/*  factory PhotosModel.fromJson(Map<dynamic, dynamic> json) => PhotosModel(
        previewURL: json['previewURL'] as String,
      );

  Map<String, dynamic> toJson() {
    return <String, dynamic>{'previewURL': previewURL};
  }*/

/*  @override
  String toString() {
    return 'PhotosModel{url: $previewURL}';
  }*/
/*factory PhotosModel.fromJson(Map<String, dynamic> json) {
  return PhotosModel(url: json['url'] as String);
}*/

  factory PhotosModel.fromJson(Map<dynamic, dynamic> json) =>
      _commentFromJson(json);

  Map<dynamic, dynamic> toJson() => photosModelToJson(this);
}

PhotosModel _commentFromJson(Map<dynamic, dynamic> json) {
  return PhotosModel(
    previewURL: json['previewURL'],
  );
}

Map<dynamic, dynamic> photosModelToJson(PhotosModel instance) => <dynamic, dynamic>{
  'previewURL': instance.previewURL,
};

and that's my service class. I make a list getPhotos() method but doesn't work anyway. import 'dart:convert';

import 'package:abcde/services/photos_model.dart';
import 'package:http/http.dart';

const MY_API_KEY = '26711456-bde74f403cb42e77029bc1678';
const appUrl = 'https://pixabay.com/api/';

class PhotosService {
  Future getData(String url) async {
    print('Calling url: $url');
    final response = await get(Uri.parse(url));
    if (response.statusCode == 200) {
      return response.body;
    } else {
      print(response.statusCode);
    }
  }
 List<PhotosModel> dataList = [];
  Future<List<PhotosModel>> getPhotos({String? query}) async {
    final photosData = await getData(
        '$appUrl?&key=$MY_API_KEY&q=$query');
    var data =json.decode(photosData);
    data.forEach((element) {
dataList.add(PhotosModel.fromJson(element));
    });

    print('this is photos data: $photosData');
    return dataList;

  }
}

that's the error it shows me The following NoSuchMethodError was thrown building: The method '[]' was called on null. Receiver: null Tried calling:

and that's my card widget import 'package:flutter/material.dart';

Widget photoCard(String url) {
  return Card(
    child: Image(
      image: NetworkImage(url),
    ),
  );
}

for api I use this web-page:

https://pixabay.com/api/docs/#api_search_images

thank you very much in advance

CodePudding user response:

Working Example

main.dart

===============

import 'package:demo_app/photo_page.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const PhotosPage(),
    );
  }
}

==============

photo_service.dart

====================

import 'dart:convert';

import 'package:http/http.dart';

const apiKey = '26711456-bde74f403cb42e77029bc1678';
const appUrl = 'https://pixabay.com/api/';

class PhotosService {
  Future getData(String url) async {
    print('Calling url: $url');
    final response = await get(Uri.parse(url));
    if (response.statusCode == 200) {
      return response.body;
    } else {
      print(response.statusCode);
    }
  }

  List<PhotosModel> dataList = [];
  Future<List<PhotosModel>> getPhotos(String query) async {
    final photosData = await getData('$appUrl?key=$apiKey&q=$query');
    var data = json.decode(photosData);
    var items = data["hits"];
    items.forEach((element) {
      dataList.add(PhotosModel.fromJson(element));
    });

    print('this is photos data: $photosData');
    return dataList;
  }
}

class PhotosModel {
  String previewURL;

  PhotosModel({required this.previewURL});

  factory PhotosModel.fromJson(Map<dynamic, dynamic> json) =>
      _commentFromJson(json);

  Map<dynamic, dynamic> toJson() => photosModelToJson(this);
}

PhotosModel _commentFromJson(Map<dynamic, dynamic> json) {
  return PhotosModel(
    previewURL: json['previewURL'],
  );
}

Map<dynamic, dynamic> photosModelToJson(PhotosModel instance) =>
    <dynamic, dynamic>{
      'previewURL': instance.previewURL,
    };

=========================

photo_page.dart

=============

import 'package:demo_app/photo_service.dart';
import 'package:flutter/material.dart';

class PhotosPage extends StatefulWidget {
  const PhotosPage({Key? key}) : super(key: key);
  static const String pathId = 'Photos page';

  @override
  State<PhotosPage> createState() => _PhotosPageState();
}

class _PhotosPageState extends State<PhotosPage> {
  PhotosService photosService = PhotosService();
  @override
  void initState() {
    super.initState();
    photosService.getPhotos("flower");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Photos'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(children: [
          _getProductTypeList(),
        ]),
      ),
    );
  }

  Widget _buildListItem(
      BuildContext context, AsyncSnapshot<dynamic> snapshot, int index) {
    final photoItem = snapshot.data[index].previewURL;
    print('photoItem is $photoItem');
    return photoCard(photoItem);
  }

  Widget _buildList(BuildContext context, AsyncSnapshot<dynamic> snapshot) {
    var values = snapshot.data;
    return ListView.builder(
      itemCount: snapshot.hasData ? snapshot.data.length : 0,
      itemBuilder: (context, index) {
        return _buildListItem(context, snapshot, index);
      },
    );
  }

  Widget _getProductTypeList() {
    return Expanded(
      child: FutureBuilder(
        future: photosService.getPhotos("flower"),
        builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(
              child: LinearProgressIndicator(),
            );
          }
          return _buildList(context, snapshot);
        },
      ),
    );
  }
}

Widget photoCard(String url) {
  return Card(
    child: Image(
      image: NetworkImage(url),
    ),
  );
}
  • Related