I am currently building an app to get a data from a json api.
I want to get the number 54 from the json code.
here is the json link
I have tried making model class of the json api here
class TeerModel{
String text;
TeerModel(this.text);
TeerModel.fromJson(Map<String, dynamic>parsedJson){
text = parsedJson['text'];
}
}
But I can't get the result so i removed it
Here is the code
import 'package:flutter/material.dart';
import 'package:http/http.dart' show get;
import 'models/teer_model.dart';
import 'dart:convert';
class Appss extends StatefulWidget {
#override
_AppssState createState() => _AppssState();
}
class _AppssState extends State<Appss> {
String result = "1S";
void fetchData ()async{
var response1 = await get("http://motyar.info/webscrapemaster/api/?url=http://teertoday.com/&xpath=/html/body/div[5]/div/table/tbody/tr[3]/td[1]#vws");
var teerModel = json.decode(response1.body);
var line = teerModel["text"].replaceAll(new RegExp(r"(\s\n)"), "");
print(line);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("Teer result"),),
floatingActionButton: FloatingActionButton(
onPressed: fetchData,
),
body: Center(
child: Text("The result is: $result"),
),
),
);
}
}
I only want to get the number 54 from "text" so I use regex
I expected the output will be 54 but instead I get this error
If you look at your json, you will see that it is entirely surrounded by [...], meaning that it is a json array. json.decode will convert this into a Dart List<Map<String, dynamic>>. It looks like you want the first / zero'th element of this array/list.
Change:
var line = teerModel["text"].replaceAll(new RegExp(r"(\s\n)"), "");
to
var line = teerModel[0]["text"].replaceAll(new RegExp(r"(\s\n)"), "");
Don't forget to call setState so that your widget rebuilds itself.
Related
I am currently building an app to get a data from a json api.
I want to get the number 54 from the json code.
here is the json link
I have tried making model class of the json api here
class TeerModel{
String text;
TeerModel(this.text);
TeerModel.fromJson(Map<String, dynamic>parsedJson){
text = parsedJson['text'];
}
}
But I can't get the result so i removed it
Here is the code
import 'package:flutter/material.dart';
import 'package:http/http.dart' show get;
import 'models/teer_model.dart';
import 'dart:convert';
class Appss extends StatefulWidget {
#override
_AppssState createState() => _AppssState();
}
class _AppssState extends State<Appss> {
String result = "1S";
void fetchData ()async{
var response1 = await get("http://motyar.info/webscrapemaster/api/?url=http://teertoday.com/&xpath=/html/body/div[5]/div/table/tbody/tr[3]/td[1]#vws");
var teerModel = json.decode(response1.body);
var line = teerModel["text"].replaceAll(new RegExp(r"(\s\n)"), "");
print(line);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("Teer result"),),
floatingActionButton: FloatingActionButton(
onPressed: fetchData,
),
body: Center(
child: Text("The result is: $result"),
),
),
);
}
}
I only want to get the number 54 from "text" so I use regex
I expected the output will be 54 but instead I get this error
If you look at your json, you will see that it is entirely surrounded by [...], meaning that it is a json array. json.decode will convert this into a Dart List<Map<String, dynamic>>. It looks like you want the first / zero'th element of this array/list.
Change:
var line = teerModel["text"].replaceAll(new RegExp(r"(\s\n)"), "");
to
var line = teerModel[0]["text"].replaceAll(new RegExp(r"(\s\n)"), "");
Don't forget to call setState so that your widget rebuilds itself.
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:carousel_pro/carousel_pro.dart';
import 'package:http/http.dart' as http;
class Home extends StatelessWidget
{
#override
Widget build(BuildContext context)
{
return MyApp(post: fetchPost());
}
}
Future<Post> fetchPost() async {
final response = await http.get('https://en.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro&explaintext&redirects=1&titles=Zambia');
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
return Post.fromJson(json.decode(response.body));
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
class Post {
final int pageid;
final int ns;
final String title;
final String extract;
Post({this.pageid, this.ns, this.title, this.extract});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
pageid: json['pageid'],
ns: json['ns'],
title: json['title'],
extract: json['extract'],
);
}
}
class ImageCarousel extends StatelessWidget
{
final carousel = Carousel(
showIndicator: false,
boxFit: BoxFit.cover,
images: [
AssetImage('assets/images/animals.jpg'),
AssetImage('assets/images/bigfalls.jpg'),
AssetImage('assets/images/resort.jpg'),
AssetImage('assets/images/soca.jpg'),
AssetImage('assets/images/towncity.jpg')
],
animationCurve: Curves.fastOutSlowIn,
animationDuration: Duration(microseconds: 20000),
);
#override
Widget build(BuildContext context)
{
double screenHeight = MediaQuery.of(context).size.height / 3;
return ListView(
children: <Widget>[
Container(
height: screenHeight,
color: Colors.red,
child: carousel,
),
const Text('About Zambia', style: TextStyle(fontWeight: FontWeight.bold)),
],
);
}
}
class MyApp extends StatelessWidget {
final Future<Post> post;
MyApp({Key key, this.post}) : super(key: key);
#override
Widget build(BuildContext context) {
return new Container(
child: FutureBuilder<Post>(
future: post,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.title);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner
return CircularProgressIndicator();
},
),
);
}
}
I'm using the example in flutter's documentation on how to fetch data from the internet (https://flutter.io/docs/cookbook/networking/fetch-data), and in place of https://jsonplaceholder.typicode.com/posts/1 I'm using ( https://en.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro&explaintext&redirects=1&titles=Zambia ) but for some reason, I can't get the information to be displayed on my App, forgive the ignorance but I'm new to programming and flutter...
You are parsing the json in the wrong way: the json from that url has a different structure, the keys you are trying to fetch are nested inside "query":{"pages":{"34415" while you are searching for them at the top level.
E.g. in this case, this :
pageid: json['pageid']
should be:
pageid: json['query']['pages']['34415']['pageid']
But it works only in this specific case. Instead, you should first fetch all the pages you get by that query from json['query']['pages'] then loop over the keys (the ids of every page got) and fetch the pages.
I am trying to fetch the data from json api and to be listed in the drop down list but i am hitting with The method 'map' was called on null error.
import "package:flutter/material.dart";
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() => runApp(MaterialApp(
title: "Hospital Management",
home: MyApp(),
));
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _mySelection;
final String url = "http://webmyls.com/php/getdata.php";
List data;
Future<String> getSWData() async {
var res = await http
.get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
var resBody = json.decode(res.body);
setState(() {
data = resBody;
});
print(resBody);
return "Sucess";
}
#override
void initState() {
super.initState();
this.getSWData();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text("Hospital Management"),
),
body: new Center(
child: new DropdownButton(
items: data.map((item) {
return new DropdownMenuItem(
child: new Text(item['item_name']),
value: item['id'].toString(),
);
}).toList(),
onChanged: (newVal) {
setState(() {
_mySelection = newVal;
});
},
value: _mySelection,
),
),
);
}
}
The error from the debug consol
flutter: The method 'map' was called on null.
flutter: Receiver: null
flutter: Tried calling: map<DropdownMenuItem<String>>(Closure:
(dynamic) => DropdownMenuItem<String>)
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 Object.noSuchMethod
(dart:core/runtime/libobject_patch.dart:48:5)
I am expecting to show the list of data from the json api in the drop down menu. I am beginner to dart and flutter. Help me out to solve the error.
data is not initialized. It is set on getSWData which is async.
A possible solution could be to have data as emptyList as an initial value.
List data = List();
If you want to display DropdownButton based on data, you can use FutureBuilder and show loader or something till data comes from getSWData
Your Api http://webmyls.com/php/getdata.php returns a list not a map. Hence, it cannot have direct property advisor_report. Consider removing it.
Data should be changed inside setState.
You never called getSWData()
Below is more improved example.
import "package:flutter/material.dart";
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() => runApp(MaterialApp(
title: "Hospital Management",
home: MyApp(),
));
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _mySelection;
final String url = "http://webmyls.com/php/getdata.php";
List data;
Future<String> getSWData() async {
var res = await http
.get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
var resBody = json.decode(res.body);
setState(() {
data = resBody;
});
print(resBody);
return "Sucess";
}
#override
void initState() {
super.initState();
this.getSWData();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text("Hospital Management"),
),
body: new Center(
child: new DropdownButton(
items: data.map((item) {
return new DropdownMenuItem(
child: new Text(item['item_name']),
value: item['id'].toString(),
);
}).toList(),
onChanged: (newVal) {
setState(() {
_mySelection = newVal;
});
},
value: _mySelection,
),
),
);
}
}
I am developing an App in flutter specifically for iOS (at this stage) and I need to add PDF file(s) to it. The problem is that flutter has no native way to display PDF files (as far as I researched).
From this tread it looks like it shouldn't it be too difficult to add PDF support to iOS devices using this plugin. However, I am still confused about how exactly to integrate it into my Flutter Application.
Any help would be appreciated!
When I was implementing the functionality for PDF viewer, there was no PDF plugin.
However, funny enough a friend at work found out that there is already a PDF viewer implemented for Flutter here, which we ended up using.
Note: At the time of writing the question, 16.08 there was not yet any plugin available. The mentioned was created on 30.08.
If you are looking for quick and easy way to display PDF, this might be the one.
pdf_flutter
Load PDF from network:
PDF.network(
'https://raw.githubusercontent.com/FlutterInThai/Dart-for-Flutter-Sheet-cheet/master/Dart-for-Flutter-Cheat-Sheet.pdf',
height: 500,
width: 300,
)
Load PDF from files:
File fileName;
PDF.file(
fileName,
height: 200,
width: 100,
)
Load PDF from assets:
PDF.assets(
"assets/pdf/demo.pdf",
height: 200,
width: 100,
)
add the dependencies in the pubspec.yaml
pubspec.yaml
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
pdf_viewer_plugin: ^1.0.0+2
path_provider: ^1.6.1
http: ^0.12.0+4
main.dart
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:pdf_viewer_plugin/pdf_viewer_plugin.dart';
import 'package:path_provider/path_provider.dart';
import 'package:http/http.dart' as http;
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String path;
#override
initState() {
super.initState();
}
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/teste.pdf');
}
Future<File> writeCounter(Uint8List stream) async {
final file = await _localFile;
// Write the file
return file.writeAsBytes(stream);
}
Future<Uint8List> fetchPost() async {
final response = await http.get(
'https://expoforest.com.br/wp-content/uploads/2017/05/exemplo.pdf');
final responseJson = response.bodyBytes;
return responseJson;
}
loadPdf() async {
writeCounter(await fetchPost());
path = (await _localFile).path;
if (!mounted) return;
setState(() {});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Plugin example app'),
),
body: Center(
child: Column(
children: <Widget>[
if (path != null)
Container(
height: 300.0,
child: PdfViewer(
filePath: path,
),
)
else
Text("Pdf is not Loaded"),
RaisedButton(
child: Text("Load pdf"),
onPressed: loadPdf,
),
],
),
),
),
);
}
}
there working code -
Add this plugin to pubspec.yaml -
>> flutter_full_pdf_viewer: ^1.0.6
on alert dialog positive button click I redirecting to view pdf -
Future<void> onPositiveButtonClick() async {
String _filePath = '';
String _directory = await ExtStorage.getExternalStoragePublicDirectory(ExtStorage.DIRECTORY_DOWNLOADS);
//todo geeting right directory path here
print("directory" + _directory);
_filePath = '$_directory/$fileName';
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => ActivityPdfView(_filePath)));
}
and this is my Activitypdfview to show pdf -
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_full_pdf_viewer/flutter_full_pdf_viewer.dart';
class ActivityPdfView extends StatefulWidget {
String filePath;
ActivityPdfView(String filePath){
this.filePath = filePath;
}
#override
_ActivityPdfViewState createState() => _ActivityPdfViewState();
}
class _ActivityPdfViewState extends State<ActivityPdfView> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyPDFList(widget.filePath), //call MyPDF List file
);
}
}
class MyPDFList extends StatelessWidget {
String pathPDF = "";
MyPDFList(String filePath){
this.pathPDF = filePath;
}
#override
Widget build(BuildContext context) {
return PDFViewerScaffold(
appBar: AppBar(
title: Text("Document"),
backgroundColor: Colors.deepOrangeAccent,
),
path: pathPDF
);
}
}
Depending on what's the min version your app supports, if it's iOS 11 and above, you can use PDFKit. Otherwise WebKit is also a good option.
Creating a earthquake information app using this api:
https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson
But getting this error after running application:
Error: A value of type 'dart.core::List<#lib1::Data>' can't beassigned to a variable of type 'dart.core::List<#lib2::Data>'.
E/flutter ( 9986): Try changing the type of the left hand side, or casting the right hand side to 'dart.core::List<#lib2::Data>'.
E/flutter ( 9986): _quakes = quakes;
My flutter version: Flutter 0.5.7-pre.100 • channel master
Codes: api.dart
import 'dart:async';
import 'dart:convert';
import 'package:flutter_layout/project/quake/models/quake.dart';
import 'package:flutter_layout/project/quake/models/serializers.dart';
import 'package:http/http.dart' as http;
const String baseUrl = 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson';
Future<List<Data>> getQuake() async {
final response = await http.get((Uri.parse(baseUrl)));
print("${response.toString()}");
Quake quake = serializers.deserializeWith(Quake.serializer, json.decode(response.body));
return quake.features.map((Properties properties) => properties.properties).toList();
}
quake.dart
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
part 'quake.g.dart';
abstract class Quake implements Built<Quake, QuakeBuilder> {
BuiltList<Properties> get features;
Quake._();
factory Quake([updates(QuakeBuilder b)]) = _$Quake;
static Serializer<Quake> get serializer => _$quakeSerializer;
}
abstract class Properties implements Built<Properties, PropertiesBuilder> {
Data get properties;
Properties._();
factory Properties([updates(PropertiesBuilder b)]) = _$Properties;
static Serializer<Properties> get serializer => _$propertiesSerializer;
}
abstract class Data implements Built<Data, DataBuilder> {
double get mag;
String get place;
Data._();
factory Data([updates(DataBuilder b)]) = _$Data;
static Serializer<Data> get serializer => _$dataSerializer;
}
QuakeApp.dart
import 'package:flutter/material.dart';
import 'QuakeListView.dart';
import 'models/api.dart';
import 'models/quake.dart';
class QuakeApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return QuakeAppState();
}
}
class QuakeAppState extends State<QuakeApp>{
List<Data> _quakes = [];
#override
void initState() {
super.initState();
getQuake().then((quakes){
_quakes = quakes;
});
}
List<QuakeListItem> buildListWidget(){
return _quakes.map((post) => QuakeListItem(
mag: post.mag,
place: post.place,
)).toList();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Quake App"),
centerTitle: true,
),
body: RefreshIndicator(
onRefresh: () async{
getQuake().then((quakes){
setState(() {
_quakes = quakes;
print("${quakes.length}");
});
});
},
child: AnimatedCrossFade(
duration: Duration(microseconds: 300),
firstChild: Center(
child: CircularProgressIndicator(),
),
secondChild: ListView(
children: buildListWidget(),
),
crossFadeState: _quakes != null ? CrossFadeState.showSecond : CrossFadeState.showFirst,
),
),
);
}
}
Any Solution?
I guess this is the known issue https://github.com/dart-lang/sdk/issues/33076
Do not use relative imports in lib/main.dart (only 'package:...' imports)
and do not import lib/main.dart from any other file.