How to display images, received from an API response in flutter? - api

I am using the http Dart package to send a GET request to the MapQuest Static Maps API to obtain an image. However, the response to this request directly returns an image, and not a Uri, or maybe I am doing something wrong.
Can you please help me display the received image?
Here's the request Code:
final http.Response response = await http.get(
'https://www.mapquestapi.com/geocoding/v1/address?key=[MYAPIKEY]&inFormat=kvp&outFormat=json&location=${address}&thumbMaps=false&maxResults=1');
final decodedResponse = json.decode(response.body);
setState(() {
_coords = decodedResponse['results'][0]['locations'][0]['latLng'];
});
final http.Response staticMapResponse = await http.get(
'https://www.mapquestapi.com/staticmap/v5/map?key=[MYAPIKEY]&center=${coords['lat']},${coords['lng']}&zoom=13&type=hyb&locations=${coords['lat']},${coords['lng']}&size=500,300#2x');
The coordinates are received from the Geocoding API of MapQuest which is an async request.

As suggested by Günter Zöchbauer I included the Request Url directly in my Image.network() widget and it worked.
Here's the Code:
void getStaticMapCoordinates(String address) async {
if (address.isEmpty) {
return;
}
final http.Response response = await http.get(
'https://www.mapquestapi.com/geocoding/v1/address?key=[APIKEY]&inFormat=kvp&outFormat=json&location=${address}&thumbMaps=false&maxResults=1');
final decodedResponse = json.decode(response.body);
setState(() {
_coords = decodedResponse['results'][0]['locations'][0]['latLng'];
});
}
Widget _buildStaticMapImage() {
if(_coords == null) {
return Image.asset('assets/product.jpg');
}
return FadeInImage(
image: NetworkImage(
'https://www.mapquestapi.com/staticmap/v5/map?key=[APIKEY]&center=${_coords['lat']},${_coords['lng']}&zoom=13&type=hyb&locations=${_coords['lat']},${_coords['lng']}&size=500,300#2x'),
placeholder: AssetImage('assets/product.jpg'),
);
}
The getStaticMapCoordinates function executes everytime the user changes the address field and as a result of setState, the Image Widget re-renders.

I used Image class to create an in-memory image object from the response body in a byte stream form.
var _profileImage = Image.memory(response.bodyBytes).image;
Now you can directly load this image in your component.

If a image is the repose from your URL:
//...
child: new ClipRRect(
borderRadius: new BorderRadius.circular(30.0),
child: Image.network('https://www.mapquestapi.com/staticmap/v5/map?key=[MYAPIKEY]&center=${coords['lat']},${coords['lng']}&zoom=13&type=hyb&locations=${coords['lat']},${coords['lng']}&size=500,300#2x',
fit: BoxFit.cover,
height: 60.0, width: 60.0))
//...
if you need to parse:
final response = await http
.get('https://www.mapquestapi.com/staticmap/v5/map?key=[MYAPIKEY]&center=${coords['lat']},${coords['lng']}&zoom=13&type=hyb&locations=${coords['lat']},${coords['lng']}&size=500,300#2x');
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
return json.decode(response.body)["imageURL"]; // <------- DO THE PARSING HERE AND THEN PASS THE URL TO THE ABOVE EXAMPLE
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}

Sometimes fetching image from URL with complex headers are cumbersome. So at that time, we can use the header map directly in the NetworkImage widget and it works like a charm-
.
.
child: CircleAvatar(
backgroundImage:
NetworkImage("www.mypropic.com",headers:getTokenHeaders());)
.
.
static Map<String, String> getTokenHeaders() {
Map<String, String> headers = new Map();
headers['Authorization'] = _bearerToken!;
headers['content-type'] = 'application/json';
return headers;
}

You can add the headers to the NetworkImage widget like :
NetworkImage( "your endpoint URL ", headers: {header:value})
Below link has more information.
https://api.flutter.dev/flutter/widgets/Image/Image.network.html

Related

problem in making http.get() request in flutter

i am learing about api's and http request in flutter and i am facing problem in making a get request as in any tutorial they are directly pasting string url inside get as parameter but when i post it as string it is showing error: The argument type 'String' can't be assigned to the parameter type 'Uri'.
can any one help me in this :
this is my sample code :
import 'dart:convert' as convert;
import 'package:http/http.dart' as http;
void main(List<String> arguments) async {
// This example uses the Google Books API to search for books about http.
// https://developers.google.com/books/docs/overview
var url = 'https://www.googleapis.com/books/v1/volumes?q={http}';
// Await the http get response, then decode the json-formatted response.
var response = await http.get(url); // i am getting error here
if (response.statusCode == 200) {
var jsonResponse = convert.jsonDecode(response.body);
var itemCount = jsonResponse['totalItems'];
print('Number of books about http: $itemCount.');
} else {
print('Request failed with status: ${response.statusCode}.');
}
}
here is image of my code with error
enter image description here
first import http as http
import 'package:http/http.dart' as http;
then parse your link to Uri using
var url = Uri.parse('https://www.googleapis.com/books/v1/volumes?q={http}');
http.Response response = await http.get(url);
try {
if (response.statusCode == 200) {
String data = response.body;
var decodedData = jsonDecode(data);
return decodedData;
} else {
return 'failed';
}
} catch (e) {
return 'failed';
}
If still doesn't work try this:
import 'package:http/http.dart';
var response = get(Uri.parse('https://www.google.com'));
Try this (Add http to pubspec.yaml under dependencies):
import 'package:http/http.dart' as http;
var response = http.get(Uri.parse('https://www.google.com'));
You passing string the error says need an uri so create an uri and use in it.
var uri = new Uri.http("example.org", "/path", { "q" : "{http}" });
First of all, check your pubspec.yaml file and HTTP version. It should be the actual one you can find here: https://pub.dev/packages/http/install
For example, it is:
http: ^0.12.2
at the moment
Here is my code and it works well:
main.dart
import 'package:flutter/material.dart';
import 'package:stackowerflow/my_app.dart';
void main() {
runApp(MyApp());
}
my_app.dart
import 'dart:convert' as convert;
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class MyApp extends StatelessWidget {
Future<void> stackHelp() async {
var url = 'https://www.googleapis.com/books/v1/volumes?q={http}';
// Await the http get response, then decode the json-formatted response.
var response = await http.get(url);
if (response.statusCode == 200) {
var jsonResponse = convert.jsonDecode(response.body);
var itemCount = jsonResponse['totalItems'];
print('Number of books about http: $itemCount.');
} else {
print('Request failed with status: ${response.statusCode}.');
}
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView '),
),
body: Container(
child: TextButton(onPressed: stackHelp, child: Text('Push me')),
),
),
);
}
}
RESULT
flutter: Number of books about http: 485.

how to get server response of a POST api in flutter

I am new to flutter and I am using mongodb to save the credentials from signup page. When tried to give credentials that already exists server shows a response - 'user already exits' this response was viewed in postman. I am able to get statusCode but I am unable to get the same response in flutter. below is my flutter code.
Future<String> uploadImage(filename) async {
var request = http.MultipartRequest('POST', Uri.parse(serverReceiverPath));
request.files.add(await http.MultipartFile.fromPath('file', filename));
var res = await request.send();
print(res.statusCode);
return null;
}
To get the body response, use res.stream.bytesToString()
Complete code:
Future<String> uploadImage(filename) async {
var request = http.MultipartRequest('POST', Uri.parse(serverReceiverPath));
request.files.add(await http.MultipartFile.fromPath('file', filename));
var res = await request.send();
print(res.statusCode); // status code
var bodyResponse = await res.stream.bytesToString(); // response body
print(bodyResponse);
return null;
}

how to refresh message stream for chat inbox in flutter

I'm new to the flutter, I start to create a simple messenger app using flutter and flutter stream to handle API call for get message content.
also created the message controller to update and refresh the message list
class MessageService {
Client httpClient = Client();
List<MessageModal> _messageList = [];
Future<AppConfig> _getApiURL() async {
final config = await AppConfig.forEnvironment('dev');
return config;
}
Future<List<MessageModal>> getMessageThread(
String senderId, String receiverId) async {
var config = await _getApiURL();
var url = config.baseUrl + "message/history";
final response = await httpClient.post(url,
headers: {"content-type": "application/json"},
body: json.encode({
"senderId": senderId,
"receiverId": receiverId,
}));
if (response.statusCode == 200) {
_messageList = messageListFromJson(response.body);
} else {
_messageList = [];
}
return _messageList;
}
}
Here is the message service class for fetch API data
class MessageService {
Client httpClient = Client();
List<MessageModal> _messageList = [];
Future<AppConfig> _getApiURL() async {
final config = await AppConfig.forEnvironment('dev');
return config;
}
Future<List<MessageModal>> getMessageThread(
String senderId, String receiverId) async {
var config = await _getApiURL();
var url = config.baseUrl + "message/history";
final response = await httpClient.post(url,
headers: {"content-type": "application/json"},
body: json.encode({
"senderId": senderId,
"receiverId": receiverId,
}));
if (response.statusCode == 200) {
_messageList = messageListFromJson(response.body);
} else {
_messageList = [];
}
return _messageList;
}
}
Here is the ui preview to create the message list preview
StreamBuilder<List<MessageModal>> _buildStreamBuilder() {
return StreamBuilder<List<MessageModal>>(
// stream: _messageService.getMessageThread("UID1", "UID2").asStream(),
stream: streamController.counter,
initialData: _messageList,
builder:
(BuildContext context, AsyncSnapshot<List<MessageModal>> snapshot) {
print(snapshot.data);
if (snapshot.hasError) {
print(snapshot.error);
return Center(
child: Text("Something went wrong!"),
);
} else if (snapshot.hasData) {
List<MessageModal> messages = snapshot.data;
return _buildMessageHistory(messages);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
);
}
I need to do the messages update and also keep updating (send the API call and fetch data to stream) the message preview. can anybody help me on this one.
It's been a while since this question was originally asked. Since then the Stream Chat Flutter support has improved a lot. Implementing what this question asks is now really easy, with varying levels of customisability.
Pre-built UI widgets package : https://pub.dev/packages/stream_chat_flutter
This package is plug and play to add chat support, with a lot of customisability options.
If you want more control: https://pub.dev/packages/stream_chat_flutter_core
This package provides convenient builders to enable you to build your own UI components. It does the heavy lifting for you but will require more implementation on your side.
If you want low level control:
https://pub.dev/packages/stream_chat
Check out the tutorial for an easy getting started guide: https://getstream.io/chat/flutter/tutorial/
See here for awesome Stream examples of what you can build: https://github.com/GetStream/flutter-samples
Video tutorials: https://www.youtube.com/playlist?list=PLNBhvhkAJG6t-BxkRAnSqa67lm5C1mpKk

does the data sent to the server using http Post update the servers API url?

Im a newbie to flutter so please if you think the question context is wrong update it, im fetching a data from an SQl server to my flutter app, and i also want to send the users info back to the server after they fill out a form, im using the http.post and i get the response’s body correctly but when i open the Server Url (api url) i dont see it updated with the new info i posted to it, can someone please tell me how Post is supposed to work?
I'm new to Flutter too, this is a working example of how i understand it
class HttpService {
createUser(String name, String lastname) async {
Map data = {'name': name, 'lastname': lastname};
var body = json.encode(data);
var jsonResponse = null;
var response = await http.post(serverUrl + "/create/",
headers: {
HttpHeaders.authorizationHeader: '**Token_here_if_you_use_it**',
HttpHeaders.contentTypeHeader: "application/json",
}, body: body);
jsonResponse = json.decode(response.body);
if (response.statusCode == 201) {
jsonResponse = json.decode(response.body);
if (jsonResponse != null) {
print(jsonResponse.toString());
}
} else {
print(jsonResponse.toString());
}
}
}
In your main.dart :
final HttpService httpService = HttpService();
httpService.createUser(name,lastname);

Custom 404 response model

I want to provide a custom reponse for all 404s on our API. For example:
{
"message": "The requested resource does not exist. Please visit our documentation.."
}
I believe the following result filter works for all cases within the MVC pipeline:
public class NotFoundResultFilter : ResultFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext context)
{
var result = context.Result as NotFoundResult;
if (result != null)
{
context.Result = new HttpNotFoundResult(); // My custom 404 result object
}
}
}
But, when a URL requested does not match an action route, the above filter is not hit. How could I best intercept these 404 responses? Would this require middleware?
Yes, you need to use middleware, as filter is only for MVC.
You may, as always, write your own middleware
app.Use(async (context, next) =>
{
await next();
if (context.Response.StatusCode == 404)
{
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonConvert.SerializeObject("your text"), Encoding.UTF8);
}
});
Or use built-in middlware StatusCodePagesMiddleware, but as you want to handle only one status, this is an extra functionality. This middleware can be used to handle the response status code is between 400 and 600 .You can configure the StatusCodePagesMiddleware adding one of the following line to the Configure method (example from StatusCodePages Sample):
app.UseStatusCodePages(); // There is a default response but any of the following can be used to change the behavior.
// app.UseStatusCodePages(context => context.HttpContext.Response.SendAsync("Handler, status code: " + context.HttpContext.Response.StatusCode, "text/plain"));
// app.UseStatusCodePages("text/plain", "Response, status code: {0}");
// app.UseStatusCodePagesWithRedirects("~/errors/{0}"); // PathBase relative
// app.UseStatusCodePagesWithRedirects("/base/errors/{0}"); // Absolute
// app.UseStatusCodePages(builder => builder.UseWelcomePage());
// app.UseStatusCodePagesWithReExecute("/errors/{0}");
Try this:
app.Use( async ( context, next ) =>
{
await next();
if ( context.Response is { StatusCode: 404, Body: { Length: 0 }, HasStarted: false } )
{
context.Response.ContentType = "application/problem+json; charset=utf-8";
string jsonString = JsonConvert.SerializeObject(errorDTO);
await context.Response.WriteAsync( jsonString, Encoding.UTF8 );
}
} );