简体   繁体   中英

send json data to a new screen Flutter

i want to send a json object to a new dart file and use it there. In the first file is a listview and when you tap on the listtile the secondscreen(jobdetail) is called, and with the call i want to send all the json information to the secondscreen(jobdetail) and print it into the console. You don't have to correct my approach if you have a different better one.

This is how i tried it: First screen:

onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => JobDetail(),
                  // Pass the arguments as part of the RouteSettings. The
                  // DetailScreen reads the arguments from these settings.
                  settings: RouteSettings(
                    arguments: jsonData[index],
                  ),
                ),
              );
            },

Secondscreen(jobdetail):

class JobDetail extends StatelessWidget {

@override
Widget build(BuildContext context) {
final jsonData = ModalRoute.of(context).settings.arguments;
print(jsonData.titel);
return new MaterialApp(
  debugShowCheckedModeBanner: false,
  title: 'Flutter App with MYSQL',
  home: new MyHomePage(),

);
}
}

Future<dynamic> senddata() async {
final response = await http.post(
  "https://www.falseurl.php", body: {
"status": "0",
"Id": "5",
"JobBlocksInProres": "0",
"IdJB": jsonData.titel,
});

var datauser = json.decode(response.body);

String jsonsDataString = datauser.toString();
dynamic Data = jsonDecode(jsonsDataString);

print(Data);


return Data;
}

I get this Error:

lib/JobDetail.dart:15:20: Error: The getter 'titel' isn't defined for the class 'Object'.
 - 'Object' is from 'dart:core'.
Try correcting the name to the name of an existing getter, or defining a getter or field     named 'titel'.
print(jsonData.titel);
               ^^^^^
lib/JobDetail.dart:31:13: Error: Getter not found: 'jsonData'.
"IdJB": jsonData.id,
        ^^^^^^^^
lib/JobDetail.dart:37:11: Error: Can't declare 'jsonData' because it was already used in this scope.
  dynamic jsonData = jsonDecode(jsonsDataString);
      ^^^^^^^^
lib/JobDetail.dart:31:13: Context: Previous use of 'jsonData'.
"IdJB": jsonData.id,
        ^^^^^^^^
lib/JobDetail.dart:39:9: Error: Getter not found: 'jsonData'.
  print(jsonData);
    ^^^^^^^^
lib/JobDetail.dart:42:10: Error: Getter not found: 'jsonData'.
  return jsonData;

Thanks for any answer

New Code First screen:

import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

import 'package:navigation/JobDetail.dart';

class Muensterboerse extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
  return new MaterialApp(
  debugShowCheckedModeBanner: false,
  title: 'Flutter App with MYSQL',
  home: new MyHomePage(),

  );
  }
  }

Future<dynamic> senddata() async {

  final response = await http.post(
      "https://www.falseurl.php", body: {
      "status": "0",
  });


  var datauser = json.decode(response.body);

  String jsonsDataString = datauser.toString();
  dynamic jsonData = jsonDecode(jsonsDataString);

  print(jsonData);


  return jsonData;
}

class Job {
  final String title;
  // Other properties

  Job({this.title});

 factory Job.fromJSON(Map<String, dynamic> map) {
    return Job(
      title: map['title'],
    );
  }
}

class JobDetailScreenArg {
  final Job job;

  JobDetailScreenArg(this.job);
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  dynamic jsonData;


  callSendData() async {
      jsonData = await senddata();
      setState(() {});
  }

//lol
  @override
  void initState() {
    callSendData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: jsonData == null
            ? Center(child: CircularProgressIndicator())
            : ListView.builder(
            padding: const EdgeInsets.all(16.0),
            itemCount: jsonData == null ? 0 : jsonData.length,
            itemBuilder: (context, index) {
              return ListTile(

                leading: CircleAvatar(
                  backgroundImage:     NetworkImage('https://kinsta.com/de/wp-content/uploads/sites/5/2019/09/wordpress-loggst-url-1024x512.jpg'),
              radius: 27,
            ),

            title: Text(
              jsonData[index]["titel"],
            ),
            subtitle: Text(jsonData[index]["nam_ersteller"]),
            trailing: Text(
              '25 Km',
              style: TextStyle(color: Colors.grey,
                fontSize: 12,
                decoration: TextDecoration.none,
                fontFamily: 'Roboto',),

            ),
            onTap: () {

              JobDetailScreenArg arg = JobDetailScreenArg(jsonData);
              Navigator.of(context).pushNamed('/JobDetailScreen', arguments: arg);

            },

          );
          // return _buildRow(data[index]);
        }));
  }
}

Secondscreen:

   import 'package:flutter/material.dart';

     import 'package:navigation/Muensterboerse.dart';

   class JobDetailScreen extends StatefulWidget {
     final Job job;

     JobDetailScreen(this.job);

     @override
     _JobDetailScreenState createState() => _JobDetailScreenState();
   }

   class _JobDetailScreenState extends State<JobDetailScreen> {
     @override
     Widget build(BuildContext context) {
       return Container(
         child: Text('${widget.job.title}'),
       );
     }
   }

New Error:

type 'List<dynamic>' is not a subtype of type 'Job'

First of, check out the following:

  • From the first screen, it looks to me like jsonData was decoded as dynamic type. If your jsonString is a valid JSON, please decode it as Map<String, dynamic> . eg Map<String, dynamic> data = jsonDecode(jsonString) . Be mindful of FormatException & TypeError .
  • Also, if your jsonString contains a list of items(job json objects), cast the list as shown below and map its items into Dart objects of your own.
var items = data['jobs'] as List;
List<Job> jobs = items.map<Job>((jobItem) => Job.fromJSON(jobItem)).toList();
  • You Job Dart object could be as shown below
class Job {
  final String title;
  // Other properties

  Job({this.title});

  factory Job.fromJSON(Map<String, dynamic> map) {
    return Job(
      title: map['title'],
    );
  }
}

Next, I would suggest the snippet below as a good method for sending data from on route to another.

Create an argument class for your route argument data

class JobDetailScreenArg {
  final Job job;

  JobDetailScreenArg(this.job);
}
MaterialApp(
    title: 'Jobs',
    // Start the app with the "/" named route. In this case, the app starts
    // on the FirstScreen widget.
    initialRoute: '/',
    onGenerateRoute: (RouteSettings settings) {
      switch(settings.name) {
        case '/jobDetail':
         JobDetailScreenArg args = settings.arguments;
         return _buildRoute(settings, JobDetailScreen(args.job));
        case '/':
         return _buildRoute(settings, JobsScreen());
      }
    }
  )



Route _buildRoute(RouteSettings settings, Widget screen) {
    return MaterialPageRoute(
      settings: settings,
      builder: (context) => screen,
    );
  }

Job listing screen

onTap: () {
  // job - tapped item
  JobDetailScreenArg arg = JobDetailScreenArg(job);
  Navigator.of(context).pushNamed('/jobDetail', arguments: arg);
}

Detail Screen

class JobDetailScreen extends StatefulWidget {
  final Job job;
  
  JobDetailScreen(this.job);

  @override
  _JobDetailScreenState createState() => _JobDetailScreenState();
}

class _JobDetailScreenState extends State<JobDetailScreen> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text('${widget.job.title}'),
    );
  }
}

I wouldnt say that the questions is "How do I send information to another file". What I would say is "How do I send information from one widget to another one".

To do that you can add a job property(I guess it's called Job) to the JobDetails widget and send the info like a parameter.

First Screen:

ListView.builder(
  itemCount: jobs.length,
  itemBuilder: (BuildContext context, int index) {
    var currentJob = jobs[index];
    return JobDetail(currentJob);
  }
);

Second Screen:

class JobDetail extends StatelessWidget {
  // Here you add the constructor and the parameter
  Job job;

  JobDetail(this.job)

My syntax might not be the correct one

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM