Flutter Map In Data Table

Issue

I get this error where I want to .map out some Data Row in a data table.

enter image description here

I’ve achieved this earlier in a previous situation and I understood how to do it, but it seems in this situation, things are different and seem to understand how to define the the method ‘map’. I want to achieve things like on the picture below, where the Columns headings are static and the rows are mapped out.

enter image description here

Here is the code:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:providerrest/helpers/apihelper.dart';
import 'package:providerrest/models/post.dart';
import 'package:providerrest/provider/homepageprovider.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  GlobalKey<ScaffoldState> _globalKey = GlobalKey();

  _getPosts() async {
    var provider = Provider.of<HomePageProvider>(context, listen: false);

    var postsResponse = await getPosts();
    if (postsResponse.isSuccessful) {
      provider.setPostsList(postsResponse.data, notify: false);
    } else {
      provider.mergePostsList(postsResponse.data, notify: false);
    }

    provider.setIsHomePageProcessing(false);
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _globalKey,
      appBar: AppBar(
        title: Text('Provider REST'),
      ),
      body: Consumer<HomePageProvider>(
        builder: (_, provider, __) {
          return ListView.builder(
            itemBuilder: (_, index) {
              Post post = provider.getPostByIndex(index);
              return DataTable(
                columnSpacing: 50,
                columns: <DataColumn>[
                  DataColumn(
                    label: Text(
                      'Friendly Name',
                      style: TextStyle(fontStyle: FontStyle.italic),
                    ),
                  ),
                  DataColumn(
                    label: Text(
                      'Licence Plate',
                      style: TextStyle(fontStyle: FontStyle.italic),
                    ),
                  ),
                  DataColumn(
                    label: Text(
                      'Delete',
                      style: TextStyle(fontStyle: FontStyle.italic),
                    ),
                  ),
                ],
                rows: post.map<DataRow>((e) {
                  return DataRow(
                    cells: <DataCell>[
                      DataCell(
                        Text('${e.friendlyName}'),
                      ),
                      DataCell(
                        Text('${e.licencePlate}'),
                      ),
                      DataCell(
                        Icon(Icons.delete),
                      ),
                    ],
                  );
                }).toList(),
              );
            },
            itemCount: provider.postsListLength,
          );
        },
      ),
    );
  }
}

Post Model

class Post {
  int capacity;
  String id;
  String friendlyName;
  String licencePlate;

  Post({this.capacity, this.id, this.friendlyName, this.licencePlate});

  Post.fromJson(Map<String, dynamic> json) {
    capacity = json['capacity'];
    id = json['id'];
    friendlyName = json['friendlyName'];
    licencePlate = json['licencePlate'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['capacity'] = this.capacity;
    data['id'] = this.id;
    data['friendlyName'] = this.friendlyName;
    data['licencePlate'] = this.licencePlate;
    return data;
  }
}

The API call

import 'dart:convert';

import 'package:http/http.dart';
import 'package:providerrest/models/httpresponse.dart';
import 'package:providerrest/models/post.dart';

Future<HTTPResponse<List<Post>>> getPosts() async {
  final response =
      await get('https://run.mocky.io/v3/d7a00528-176c-402f-850e-76567de3c68d');
  if (response.statusCode == 200) {
    var body = jsonDecode(response.body)['data'];
    List<Post> posts = [];
    body.forEach((e) {
      Post post = Post.fromJson(e);
      posts.add(post);
    });
    return HTTPResponse<List<Post>>(
      true,
      posts,
      message: 'Request Successful',
      statusCode: response.statusCode,
    );
  } else {
    return HTTPResponse<List<Post>>(
      false,
      null,
      message:
          'Invalid data received from the server! Please try again in a moment.',
      statusCode: response.statusCode,
    );
  }
}

and the Provider:

import 'package:flutter/foundation.dart';
import 'package:providerrest/models/post.dart';

class HomePageProvider extends ChangeNotifier {
  bool _isHomePageProcessing = true;
  List<Post> _postsList = [];

  bool get isHomePageProcessing => _isHomePageProcessing;

  setIsHomePageProcessing(bool value) {
    _isHomePageProcessing = value;
    notifyListeners();
  }

  List<Post> get postsList => _postsList;

  setPostsList(List<Post> list, {bool notify = true}) {
    _postsList = list;
    if (notify) notifyListeners();
  }

  mergePostsList(List<Post> list, {bool notify = true}) {
    _postsList.addAll(list);
    if (notify) notifyListeners();
  }

  deletePost(Post list) {
    _postsList.remove(list);

    notifyListeners();
  }

  addPost(Post post, {bool notify = true}) {
    _postsList.add(post);
    if (notify) notifyListeners();
  }

  Post getPostByIndex(int index) => _postsList[index];

  int get postsListLength => _postsList.length;
}

I thought I achieved this by making a Map toJson()method in the Post model, but it seems I’m wrong.

Thank you in advance for the help!

Solution

I suspect that your are expecting the below code.

Instead of using the ListView.builder you can use the List.generate to populate the List of data row.

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _globalKey,
      appBar: AppBar(
        title: Text('Provider REST'),
      ),
      body: Consumer<HomePageProvider>(
        builder: (_, provider, __) {
          return DataTable(
            columnSpacing: 50,
            columns: <DataColumn>[
              DataColumn(
                label: Text(
                  'Friendly Name',
                  style: TextStyle(fontStyle: FontStyle.italic),
                ),
              ),
              DataColumn(
                label: Text(
                  'Licence Plate',
                  style: TextStyle(fontStyle: FontStyle.italic),
                ),
              ),
              DataColumn(
                label: Text(
                  'Delete',
                  style: TextStyle(fontStyle: FontStyle.italic),
                ),
              ),
            ],
            rows: List.generate(provider._postsList.length, (index) {
              Post post = provider.getPostByIndex(index);
              return DataRow(
                cells: <DataCell>[
                  DataCell(
                    Text('${post.friendlyName}'),
                  ),
                  DataCell(
                    Text('${post.licencePlate}'),
                  ),
                  DataCell(
                    Icon(Icons.delete),
                  ),
                ],
              );
            }),
          );
        },
      ),
    );
  }

I hope it will help you to achieve your requirement.

Answered By – Balasubramani Sundaram

Answer Checked By – Cary Denson (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.