2

I have a JSON like this

[
  {
    "name": "A",
    "forX": [
      {
        "amount": 1
      },
            {
        "amount": 2
      }
    ],
    "forY": [
      {
        "amount": 3
      },
            {
        "amount": 4
      }
    ]
  },
  {
    "name": "B",
    "forX": [
      {
        "amount": 5
      }
    ],
    "forY": null
  }
]

How can I get the sum of the results forX.amount and forY.amount for each name?

(the result to display will be A -> forX = 3 forY = 7; B-> forX = 5)

Full code:

import 'package:flutter/material.dart';
import 'dart:convert';

List<Json> jsonFromJson(String str) => List<Json>.from(json.decode(str).map((x) => Json.fromJson(x)));

String jsonToJson(List<Json> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Json {
  Json({this.name, this.forX, this.forY});

  String name;
  List<ForX> forX;
  List<ForY> forY;

  factory Json.fromJson(Map<String, dynamic> json) => Json(
        name: json["name"] == null ? null : json["name"],
        forX: json["forX"] == null ? null : List<ForX>.from(json["forX"].map((x) => ForX.fromJson(x))),
        forY: json["forY"] == null ? null : List<ForY>.from(json["forY"].map((x) => ForY.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "name": name == null ? null : name,
        "forX": forX == null ? null : List<dynamic>.from(forX.map((x) => x.toJson())),
        "forY": forY == null ? null : List<dynamic>.from(forY.map((x) => x.toJson())),
      };
}

class ForY {
  ForY({this.amount});
  int amount;
  factory ForY.fromJson(Map<String, dynamic> json) => ForY(amount: json["amount"] == null ? null : json["amount"]);
  Map<String, dynamic> toJson() => {"amount": amount == null ? null : amount};
}

class ForX {
  ForX({this.amount});
  int amount;
  factory ForX.fromJson(Map<String, dynamic> json) => ForX(amount: json["amount"] == null ? null : json["amount"]);
  Map<String, dynamic> toJson() => {"amount": amount == null ? null : amount};
}

class JsonServices {
  static Future<List<Json>> getData() {
    String jsonString = '''
[
  {
    "name": "A",
    "forX": [
      {
        "amount": 1
      },
            {
        "amount": 2
      }
    ],
    "forY": [
      {
        "amount": 3
      },
            {
        "amount": 4
      }
    ]
  },
  {
    "name": "B",
    "forX": [
      {
        "amount": 5
      }
    ],
    "forY": null
  }
]
    ''';

    return Future.value(jsonFromJson(jsonString));
  }
}

class Sum extends StatefulWidget {
  @override
  _SumState createState() => _SumState();
}

class _SumState extends State<Sum> {
  List<Json> _json = [];
  @override
  void initState() {
    super.initState();
    setState(() {
      JsonServices.getData().then((data) {
        setState(() {
          _json = data;
        });
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        for (var j in _json)
          Row(
            children: [
              Expanded(child: Text(j.name)),
              for (int i = 0; i < j.forX.length; i++)
                if (j.forX[i].amount != null) Text('For X: ${j.forX[i].amount}'),
              if (j.forY != null)
                for (int i = 0; i < j.forY.length; i++)
                  if (j.forY != null)
                    Text(
                      'For Y: ${j.forY[i].amount}',
                    )
            ],
          ),
      ],
    );
  }
}

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: Sum(),
      ),
    );
  }
}

2
  • 1
    What have you tried yourself? Can you show us some code? Commented Apr 7, 2021 at 9:20
  • I updated full code :) Commented Apr 7, 2021 at 10:04

1 Answer 1

1

You can add a method in the Json class which does the calculation for each Item in json data as follow :

check getSummationString() method

class Json {
  Json({this.name, this.forX, this.forY});

  String name;
  List<ForX> forX;
  List<ForY> forY;

  factory Json.fromJson(Map<String, dynamic> json) => Json(
    name: json["name"] == null ? null : json["name"],
    forX: json["forX"] == null
        ? null
        : List<ForX>.from(json["forX"].map((x) => ForX.fromJson(x))),
    forY: json["forY"] == null
        ? null
        : List<ForY>.from(json["forY"].map((x) => ForY.fromJson(x))),
  );

  Map<String, dynamic> toJson() => {
    "name": name == null ? null : name,
    "forX": forX == null
        ? null
        : List<dynamic>.from(forX.map((x) => x.toJson())),
    "forY": forY == null
        ? null
        : List<dynamic>.from(forY.map((x) => x.toJson())),
  };

  String getSummationString() {
    double forXSummation = 0;
    double forYSummation = 0;
    if (this.forX != null) {
      this.forX.forEach((element) {
        forXSummation += element.amount;
      });
    }

    if (this.forY != null) {
      this.forY.forEach((element) {
        forYSummation += element.amount;
      });
    }

    return '${this.name} -> forX = $forXSummation, forY = $forYSummation;';
  }
}

Then you can use ListView to show the data for each Name as follow:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Expanded(
          child: ListView.builder(
            itemCount: _json.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(_json[index].getSummationString()),
              );
            },
          ),
        ),
      ),
    );
  }

result as follow:

enter image description here

It is better to separate logic from ui.

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

Comments

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.