I am getting this error many times in Flutter when I want to use the JsonPlaceholder API, and I downloaded a package named HTTP package in pub.dev/flutter , used in pubspec.yaml , but I can't get the data it gives the same error every time I run the application,
([ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: SocketException: Failed host lookup: 'jsonplaceholder.typicode.com' (OS Error: No address associated with hostname, errno = 7)) ,
Here is the code I used inside my stateful Widget class
import 'package:flutter/material.dart';
import 'package:http/http.dart';
class Loading extends StatefulWidget {
#override
_LoadingState createState() => _LoadingState();
}
class _LoadingState extends State<Loading> {
void getData() async{
Response response = await get('https://jsonplaceholder.typicode.com/todos/1');
print(response.body);
}
#override
initState() {
super.initState();
getData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('Loading Screen'),
),
);
}
}
The problem is in various stages.
Did not import the package right
Did not perform the operation right in the method
We will sort this out one by one. Refer to the http documentation, by selecting the link give. Now let us jump into the code
1. Importing the package right
// refer documentation as well
import 'package:http/http.dart' as http;
2. Using the method right
void getData() async{
// see the difference, it is http.get()
Response response = await http.get('https://jsonplaceholder.typicode.com/todos/1');
print('Response body: ${response.body}');
}
Now that you call your method in your initState(), you will get the data in your console.
Also, it is a good practice to take a look at the response code, if it is 200, it is OK, else return an error message.
void getData() async{
// see the difference, it is http.get()
Response response = await http.get('https://jsonplaceholder.typicode.com/todos/1');
if(response.statusCode == 200) print('Response body: ${response.body}');
else print('Some error happened, here is the status code: ${response.statusCode}')
}
Related
I am trying to follow the flutter cookbook guide for creating mockito tests. Here is the link https://docs.flutter.dev/cookbook/testing/unit/mocking.
After solving some little issues here and there with dependency conflicts I have reached a blocker I can't seem to find much information on.
When running the tests the import 'package:mocking/main.dart'; I am getting an error saying that it cannot be resolved. I am pretty new to dart, flutter, and mockito. From what I can understand this import is supposed to mock the functions from the main.dart file.
The main.dart file lives in the lib folder while the fetch_album_test.dart lives in the test folder.
I added the http(0.13.5) dependency, and the mockito(5.3.2) and build_runner(2.3.2) dev_dependency to the pubspec.yaml file and have run pub get. I also ran flutter pub run build_runner build.
I have followed the steps in the above link and also searched the web for mentions of "mocking" and "package:mocking" but I can't find anything. There are examples of building mock tests within the same .dart file as the class but I find that it would be helpful to keep the tests separate.
So what are my questions?
Why is the import 'package:mocking/main.dart'; not found?
Can this be resolved?
Is there a better solution?
The code is the same as the Flutter docs link but here it is again so you don't have to link.
lib/main.dart
`
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<Album> fetchAlbum(http.Client client) async {
final response = await client
.get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1'));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return Album.fromJson(jsonDecode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
}
class Album {
final int userId;
final int id;
final String title;
const Album({required this.userId, required this.id, required this.title});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
userId: json['userId'],
id: json['id'],
title: json['title'],
);
}
}
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({super.key});
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late final Future<Album> futureAlbum;
#override
void initState() {
super.initState();
futureAlbum = fetchAlbum(http.Client());
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: const Text('Fetch Data Example'),
),
body: Center(
child: FutureBuilder<Album>(
future: futureAlbum,
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 const CircularProgressIndicator();
},
),
),
),
);
}
}
`
test/fetch_album_test.dart
`
import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:mocking/main.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'fetch_album_test.mocks.dart';
// Generate a MockClient using the Mockito package.
// Create new instances of this class in each test.
#GenerateMocks([http.Client])
void main() {
group('fetchAlbum', () {
test('returns an Album if the http call completes successfully', () async {
final client = MockClient();
// Use Mockito to return a successful response when it calls the
// provided http.Client.
when(client
.get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1')))
.thenAnswer((_) async =>
http.Response('{"userId": 1, "id": 2, "title": "mock"}', 200));
expect(await fetchAlbum(client), isA<Album>());
});
test('throws an exception if the http call completes with an error', () {
final client = MockClient();
// Use Mockito to return an unsuccessful response when it calls the
// provided http.Client.
when(client
.get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1')))
.thenAnswer((_) async => http.Response('Not Found', 404));
expect((client), throwsException);
});
});
}
`
I have tried moving around the files, and changing the import package name and I have done a lot of searching online.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
#override
void initState() {
getData();
//calling back the request function for data.
super.initState();
}
getData() async {
var response = await http.get(Uri.parse(
"https://newsapi.org/v2/everything?q=tesla&from=2021-06-19&sortBy=publishedAt&apiKey=aef6cc5fa8bb4554a1d76e614b4b5952"));
var jsonData = jsonDecode(response.body);
//change to json type data
print(jsonData);
}
Here is the error I got when I try to request data from API :
Error Photo
try use
#override
void didChangeDependencies() {
getData();
super.didChangeDependencies();
}
instead of
#override
void initState() {
getData();
//calling back the request function for data.
super.initState();
}
Finally I got it.
I mistyped some unnecessary characters in built-in flutter io.dart file.
And sorry for my mistakes.
When I am trying to get data from the internet to use it in my app via the get method provided by the flutter http package it throws this error - The argument type 'String' can't be assigned to the parameter type 'Uri'. This is my code
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
class Loading extends StatefulWidget {
#override
_LoadingState createState() => _LoadingState();
}
class _LoadingState extends State<Loading> {
#override
void getData() async {
http.get("https://jsonplaceholder.typicode.com/todos/1")
}
void initState() {
super.initState();
getData();
}
Widget build(BuildContext context) {
return Scaffold(
body: Text("some text"),
);
}
}
First argument of http package request method is Uri type, So you have to change your code to this:
void getData() async {
final requestUrl = Uri.parse("https://jsonplaceholder.typicode.com/todos/1");
http.get(requestUrl)
}
i use laravel_echo and flutter_pusher_client packages for custom websocket. i can successfully fetch data in real time when backend sends. My data is number and message. and i send that coming number data as message to that number using sms_maintained package. My problem is how to show alltime data(past,present,future) that is coming when backend sends. It can be in anytime. should i use StreamBuilder or Animated list??. and little example would be appreciated. Here is websocket part code:
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_pusher_client/flutter_pusher.dart';
import 'package:laravel_echo/laravel_echo.dart';
import 'package:pursat_otp/provider.dart';
import 'package:sms_maintained/sms.dart';
import 'model/data_model.dart';
import 'model/pusher_model.dart';
class PusherSide extends StatefulWidget {
#override
_PusherSideState createState() => _PusherSideState();
}
class _PusherSideState extends State<PusherSide> {
FlutterPusher pusherClient;
Echo echo;
dynamic channel;
Data data;
// fetch declarations
#override
void initState() {
fetchConf();
super.initState();
}
Future<void> fetchConf() async {
try {
var response = await Provider.dio.get('/conf/pusher');
Conf conf = Conf.fromJson(response.data['conf']);
debugPrint('${conf.pusherAppKey}');
//websocket part
FlutterPusher getPusherClient() {
PusherOptions options = PusherOptions(
host: conf.host,
port: conf.port,
cluster: conf.pusherAppCluster,
encrypted: conf.encrypted);
return FlutterPusher(conf.pusherAppKey, options, lazyConnect: false);
}
pusherClient = getPusherClient();
echo = new Echo({
'broadcaster': 'pusher',
'client': pusherClient,
});
channel = echo.channel(conf.channel);
channel.listen(conf.event, (e) {
setState(() {
data = Data.fromJson(e);
debugPrint('$e');
});
});
} on DioError catch (e) {
debugPrint('${e.message}');
}
}
#override
Widget build(BuildContext context) {
// how to show that e data here using StreamBuilder or AnimatedList or any Widget. e data comes as json at anytime during a day
}
}
anyway i solved above problem using AnimatedList widget. Let me know if who needs source code.
I'm trying to return a json string in Flutter. I'm using the print function to display the output in the console. However my code is returning the String twice. Here is my code:
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() => runApp(new HomePage());
class HomePage extends StatelessWidget {
Future<http.Response> fetchPost() async{
return await http.get('https://api.npoint.io/8c7aafe809d73af5f2b9');
}
void Data() async {
var jsonString = await fetchPost();
print(jsonString.body);
}
#override
Widget build(BuildContext context) {
Data();
return new MaterialApp(
home: new Center(
child: new Text('Data'),
),
);
}
}
The build method is called twice causing the whole widget to be called again. Consider converting StatelessWidget to StatefulWidget and add your http call method in
#overridde
initState() {
your code
}
I had the same issue and solved using try catch
Future<http.Response> fetchPost() async{
try{
return await http.get('https://api.npoint.io/8c7aafe809d73af5f2b9');
}
catch (e) {
print(e);
}
}