0

I have a JSON response from RestApi like this:

    [{"_id":"5eee4b3630cff64ee216e4fb",
"assignee_user_id":"5eab4a435647780af311d3a7",
"task_name":"Another Test work",
"task_description":"Test Description",
"assignee_name":"Test Assignee",
"status":"assigned",
"assignment_date":"20-06-2020 11:15",
"assignor_name":"Test Assignor",
"assignor_remarks":[{"commentTime":"21-06-2020 05:17","comment":"Test Comment"}]}]

and the podo class build is like this:

import 'dart:convert';

List<Work> workFromMap(String str) => List<Work>.from(json.decode(str).map((x) => Work.fromMap(x)));

String workToMap(List<Work> data) => json.encode(List<dynamic>.from(data.map((x) => x.toMap())));

class Work {
    Work({
        this.id,
        this.assigneeUserId,
        this.taskName,
        this.taskDescription,
        this.assigneeName,
        this.status,        
        this.assignmentDate,
        this.assignorName,        
        this.assignorRemarks,
    });

    String id;
    String assigneeUserId;
    String taskName;
    String taskDescription;
    String assigneeName;
    String status;    
    String assignmentDate;
    String assignorName;
   
    List<AssignorRemark> assignorRemarks;

    factory Work.fromMap(Map<String, dynamic> json) => Work(
        id: json["_id"],
        assigneeUserId: json["assignee_user_id"],
        taskName: json["task_name"],
        taskDescription: json["task_description"],
        assigneeName: json["assignee_name"],
        status: json["status"],        
        assignmentDate: json["assignment_date"],        
        assignorRemarks: List<AssignorRemark>.from(json["assignor_remarks"].map((x) => AssignorRemark.fromMap(x))),
    );

    Map<String, dynamic> toMap() => {
        "_id": id,
        "assignee_user_id": assigneeUserId,
        "task_name": taskName,
        "task_description": taskDescription,
        "assignee_name": assigneeName,
        "status": status,        
        "assignment_date": assignmentDate,        
        "assignor_remarks": List<dynamic>.from(assignorRemarks.map((x) => x.toMap())),
    };
}

class AssignorRemark {
    AssignorRemark({
        this.commentTime,
        this.comment,
    });

    String commentTime;
    String comment;

    factory AssignorRemark.fromMap(Map<String, dynamic> json) => AssignorRemark(
        commentTime: json["commentTime"],
        comment: json["comment"],
    );

    Map<String, dynamic> toMap() => {
        "commentTime": commentTime,
        "comment": comment,
    };
}

and my api call is like this:

import './work.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;

Future<List<Work>> fetchWork() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  final userid = prefs.getString('user_id');
  final response =
      await http.get("https://myserver/api/work-monitor/work/?id=$userid",
    );

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
    print(response.body);
    
    
    return workFromMap(response.body);
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load Profile');
  }
}

and my screen file content is like this:

class WorkMonitor extends StatefulWidget {
  @override
  _WorkMonitorState createState() => _WorkMonitorState();
}

class _WorkMonitorState extends State<WorkMonitor> {
  Future<Work> futureMyWorkMonitor;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Work Monitor'),
      ),
      body: Container(
        child: FutureBuilder(
          future: fetchWork(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return ListView.builder(
                itemCount: snapshot.data.length,
                shrinkWrap: true,
                itemBuilder: (BuildContext context, index) {
                  Work work = snapshot.data[index];
                  //  return Text('${work.taskName}');
                  return Container(
                    padding: const EdgeInsets.all(5),
                    width: double.infinity,
                    child: Card(
                      child: Container(
                        padding: const EdgeInsets.all(20),
                        child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: <Widget>[
                              Row(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: <Widget>[
                                    Text('Subject: ',
                                        style: TextStyle(
                                          fontSize: 20,
                                          fontWeight: FontWeight.bold,
                                        )),
                                    Text(
                                      '${work.taskName}',
                                      style: TextStyle(
                                          fontSize: 20, color: Colors.black),
                                    ),
                                  ]),
                              Row(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: <Widget>[
                                    Text('Description: ',
                                        style: TextStyle(
                                          fontSize: 16,
                                          fontWeight: FontWeight.bold,
                                        )),
                                    Flexible(
                                        child: Text(
                                      '${work.taskDescription}',
                                    )),
                                  ]),
                              Row(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: <Widget>[
                                    Text('Assigned Date: ',
                                        style: TextStyle(
                                          fontSize: 16,
                                          fontWeight: FontWeight.bold,
                                        )),
                              Text(
                                '${work.assignmentDate}' ?? " ",
                                style: TextStyle(fontSize: 16),
                              ),
                                  ]),

                                Row(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: <Widget>[
                                    Text('Description: ',
                                        style: TextStyle(
                                          fontSize: 16,
                                          fontWeight: FontWeight.bold,
                                        )),
                              Text(
                                '${work.status}' ?? "Gone",
                                style: TextStyle(fontSize: 16),
                              ),
                                  ]),
                            
                            Text(
                              
                              '${work.assignorRemarks[index]}'
                              ),
                            ]),
                            
                      ),
                    ),
                  );
                },
              );
            } else if (snapshot.hasError) {
              return Text("${snapshot.error}");
            }

            // By default, show a loading spinner.
            return CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}

Only issue I am facing here is, I am not able to access/iterate over comments. How I can do this?

2
  • Why can't you access/iterate over comments? What error are you getting? Commented Jun 21, 2020 at 18:40
  • @puelo - very new to flutter, I am just trying to access like '${work.assignorRemarks}' and I am getting like an instance of `AssignorRemark' Commented Jun 21, 2020 at 18:50

1 Answer 1

1

You need to somehow also iterate through each comment inside each list item. One way (probably only for a small amount of remarks), would be a Column (or if you need scrolling you could use a SingleChildScrollView with a Column). Example:

Column(
  children: work.assignorRemarks.map<Text>((remark) {
    return Text(remark.comment);
  }).toList()
)

If you have a lot of items you are probably better of using a nested ListView

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you so much, it's working. how I can add the comment as well, which is child of assignorRemarks. can I do a return another column instead of Text and then have two Text widgets.
You mean the commentTime ?
There are variety to Widgets you could use to display this nested information. You cannot nest it inside the Text widget tho. I would recommend: api.flutter.dev/flutter/material/ListTile-class.html. Or you build one String for the information: Text('${remark.comment} (${remark.commentTime})');
Thanks.that will do. but only issue with this is like, I want the comment font- little smaller. is that possible with this solution?
Thanks Puelo for you help, I used the map<Row>(remark){ and then used two Text widgets inside Row widget

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.