I have problem in api calling i getting a geolocation of current place,i am passing the latitude&longitude
but i having a problem is i need to pass the latitude&longitude to certain format like this lat_11.3054724$75.8744252 so i can't try to concatinate the $ sign along with it,Also i am not getting any data when i pass latitude&longitude data i cannot use in api it throws
unhandled Exception: NoSuchMethodError: The getter 'latitude' was called on null.
E/flutter (27500): Receiver: null
E/flutter (27500): Tried calling: latitude
But i can print the data to Text but not pass to api
Code
Future<String> getMainbanner() async {
var latitude=_currentPosition.latitude.toString();
var longitude=_currentPosition.longitude.toString();
var response = await http.post(Urls.HOME_BANNER,
headers: {"Content-Type": "application/json"},
body: json.encode({
"banner_type": "Main_Banner",
"location": "lat_"+latitude+'$'+longitude,
}),);
Map<String, dynamic> value = json.decode(response.body);
if (response.statusCode == 200) {
var resp = response.body;
Map<String, dynamic> value = json.decode(resp);
var message = value['msg'];
var banner =value['bannerapp'][0];
for (int i = 0; i < banner.length; i++) {
var data = banner[i];
print("Data:"+data);
}
}
else
{
CustomDialogs().showErrorAlert(context, "Main Banner Image NotFound");
}
}
Code for fetching Current location
_getCurrentLocation() {
final Geolocator geolocator = Geolocator()..forceAndroidLocationManager;
geolocator
.getCurrentPosition(desiredAccuracy: LocationAccuracy.best)
.then((Position position) {
setState(() {
_currentPosition = position;
});
}).catchError((e) {
print(e);
});
}
Edit: The problem is, that _currentLocation is still null when you call _currentLocation.latitude, because _getcurrentLocation() needs some time to set it. There are different approaches to make it work, depending on how your architecture looks.
Change _getCurrentLocation() to an async function
Future<void> _getCurrentLocation() async {
final Geolocator geolocator = Geolocator()..forceAndroidLocationManager;
try {
final position = await geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.best);
setState(() {
_currentPosition = position;
});
} catch(e) {
print(e);
}
}
And await on it inside getMainbanner
Future<String> getMainbanner() async {
await _getCurrentLocation();
var latitude=_currentPosition.latitude.toString();
var longitude=_currentPosition.longitude.toString();
var response = await http.post(Urls.HOME_BANNER,
headers: {"Content-Type": "application/json"},
body: json.encode({
"banner_type": "Main_Banner",
"location": "lat_"+latitude+'$'+longitude,
}),);
Map<String, dynamic> value = json.decode(response.body);
if (response.statusCode == 200) {
var resp = response.body;
Map<String, dynamic> value = json.decode(resp);
var message = value['msg'];
var banner =value['bannerapp'][0];
for (int i = 0; i < banner.length; i++) {
var data = banner[i];
print("Data:"+data);
}
}
else
{
CustomDialogs().showErrorAlert(context, "Main Banner Image NotFound");
}
}
The problem is the $. $ is a special character in dart strings for interpolation so you have to add an escape \ before it.
See here:
https://dart.dev/guides/language/language-tour#strings
And you can make use of this string interpolation to build your string:
var latitude=_currentPosition.latitude;
var longitude=_currentPosition.longitude;
....
"location":"lat_$latitude\$$longitude"
...
Also, you don't need the toString() for latitude and longitude
Related
I'm new in Flutter. I got an issue where i cannot POST data using http after get location.
This is the code
void postData() async {
prefs = await SharedPreferences.getInstance();
bool isAutoCheckIn = prefs.getBool(helper.ISAUTO_CHECKIN) ?? false;
var sessionId = prefs.getString(helper.SESSION_ID);
var employeeId = prefs.getInt(helper.EMPLOYED_ID).toString();
var _uri = Uri.parse(
helper.CHECK_IN + employeeId);
var header = {"session-id": sessionId!};
try {
if (valid) {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.medium);
var _center = LatLng(position.latitude, position.longitude);
List<Placemark> p = await placemarkFromCoordinates(
_center.latitude, _center.longitude);
Placemark place = p[0];
var address =
"${place.street}, ${place.locality}, ${place.subAdministrativeArea}";
var body = {
"test": address
};
final response = await http.post(_uri, headers: header, body: body);
if (response.statusCode == 200) {
dynamic _data = json.decode(response.body);
}
}
} catch (err) {
throw Exception(err);
}
}
Problem comes after this code
List<Placemark> p = await placemarkFromCoordinates(
_center.latitude, _center.longitude);
It will never reach code below it. I am using http: ^0.13.5 geolocator: ^7.7.1 geocoding: ^2.0.5. Am I doing wrong here? Please kindly help me. Thank you
I'm trying to fetch both temperature and icon name from Openweathermap api. The problem occurs when I try to to fetch icon(or rather icon name).
It returns an error :
Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'
And I can't seem to find where the problem is. In other models I have other data types and it works fine, here it doesn't.
When I add icon to model, view returns null for temperature.
Here is code for weather model:
class WeatherData {
int? temp;
String? icon;
WeatherData({
this.temp,
this.icon
});
WeatherData.fromJson(dynamic json) {
var tempInKelvin = json["main"]["temp"];
temp = (tempInKelvin - 273.15).round();
icon = json["weather"]["icon"];
}
}
This is weather service:
class WeatherService {
final apiKey = "7e23369c183254302bda0471cc3f848c";
Future<WeatherData?> getWeatherForLocation(LocationData location) async {
WeatherData? weatherData;
var params = {
"lat": location.lat.toString(),
"lon": location.lon.toString(),
"city": location.city,
"appId": apiKey,
};
var url = Uri.http('api.openweathermap.org', '/data/2.5/weather', params);
Response response = await get(url);
if (response.statusCode == HttpStatus.ok) {
var jsonResponse = jsonDecode(response.body) as Map<String, dynamic>;
weatherData = WeatherData.fromJson(jsonResponse);
print("Request successful: $jsonResponse");
return weatherData;
} else {
print("Request failed with status: ${response.statusCode}");
return weatherData;
}
}
}
This is weather controller:
class WeatherController extends GetxController {
final WeatherService _weatherService = Get.find();
Rxn<LocationData> locationData = Rxn();
Rxn<WeatherData> weatherData = Rxn();
// RxString infoText = "...".obs;
String get address =>
"${locationData.value?.city},${locationData.value?.county}, ${locationData.value?.country}";
String get temperature => "${weatherData.value?.temp}";
// String get icon => "${weatherData.value?.icon}";
#override
void onInit() async {
super.onInit();
await getCurrentLocation();
await getTemperatureForCurrentLocation();
await getWeatherIcon();
}
getCurrentLocation() async {
LocationData? location = await _weatherService.getCurrentLocation();
print(location?.city);
locationData.value = location;
}
getTemperatureForCurrentLocation() async {
if (locationData.value != null) {
weatherData.value=
await _weatherService.getWeatherForLocation(locationData.value!);
// _getInfoText(weatherData.value?.temp);
}
}
}
Looking at their API docs, it seems that weather contains an array of objects (as a result, you need an integer index to figure out which one you want).
https://openweathermap.org/current
To fix it, you can simply opt to always use the first object in the weather array and take the icon/description from that:
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
Which is:
icon = json["weather"][0]["icon"];
Can you please check this:
var tempInKelvin = double.parse(json["main"]["temp"]);
or this if your number is integer:
var tempInKelvin = int.parse(json["main"]["temp"]);
I have a scenario where the following function is called again and again whenever the user hits the "Load More" button.
The problem I'm facing is, that it replaces previously loaded data with a new one. Instead, it should add to the bottom of the Listview.Builder
Future fetchData() async{
var url = "url_goes_here";
final response = await http.get(url);
if (response.statusCode == 200) {
var resBody = jsonDecode(response.body);
var data = resBody['data'] as List;
if (data.isNotEmpty) {
setState(() {
listVariable = data
.map<ModelClass>((json) => ModelClass.fromJson(json))
.toList();
});
}
}
}
List<ModelClass> listVariable =List<ModelClass>(); //describe the object that way.
--------and---------
data.map<ModelClass>((json) {
listVariable.add(ModelClass.fromJson(jsonn));
} )).toList();
You should add received data to your listVariable, not assign a new value. Try this code:
final listVariable = <ModelClass>[];
...
Future fetchData() async {
var url = "url_goes_here";
final response = await http.get(url);
if (response.statusCode == 200) {
var resBody = jsonDecode(response.body);
var data = resBody['data'] as List;
if (data.isNotEmpty) {
final list = data.map<ModelClass>((json) => ModelClass.fromJson(json));
setState(() {
listVariable.addAll(list); // HERE: addAll() instead of assignment
});
}
}
}
I was able to figure out answer myself.
setState(() {
listVariable.addAll(data
.map<ModelClass>((json) => ModelClass.fromJson(json))
.toList();
}));
#Mol0ko and #hasan karaman both are right but #Mol0ko
Makes better sense when you have a set of data to addAll to existing data.
in this code below WeatherModel tried to get current location of android phone,
my problem here is once I start runing it show NoSuchMethod Found, and it says reciever is null,
as I tried a lot of debugging just to see where is my problem.
I now understand that my problem is when I create instance of Location() in WeatherModel, longitude and latitude are null, it never gets value and I dont know why...
Sorry for my bad english :(
const apiKey = 'e3653190f2b1d4803287b3074ecfe618';
const apiWeatherURL = 'https://api.openweathermap.org/data/2.5/weather';
class WeatherModel {
Future<dynamic> getLocationWeather() async {
Location location = Location();
NetworkHelper networkHelper = NetworkHelper(
'https://api.openweathermap.org/data/2.5/weather?lat=${location.latitude}&lon=${location.longitude}&appid=$apiKey');
var weatherData = networkHelper.getData();
return weatherData;
}
}
.....
class Location {
double latitude;
double longitude;
Future<void> getCurrentLocation() async {
try {
Position _position = await Geolocator()
.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
longitude = _position.longitude;
print(longitude);
latitude = _position.latitude;
print(latitude);
} catch (e) {
print(e);
}
}
}
.........
class NetworkHelper {
NetworkHelper(this.url);
final url;
Future getData() async {
http.Response response = await http.get(url);
if (response.statusCode == 200) {
var data = jsonDecode(response.body);
print(" Sarkawtua $data");
return data;
} else
print("Error ${response.statusCode} keshay Internet");
}
}
Because you instance fields are not updated, so they are null. You have method for getting current location but it's not fired in getLocationWeather.
Future<dynamic> getLocationWeather() async {
Location location = Location();
await location.getCurrentLocation();
NetworkHelper networkHelper = NetworkHelper(
'https://api.openweathermap.org/data/2.5/weather?lat=${location.latitude}&lon=${location.longitude}&appid=$apiKey');
var weatherData = await networkHelper.getData();
return weatherData;
}
Edit: You also must await networkHelper.getData() method to get not Future Object.
Whenever trying to call future data and trying converting to List, it returns the error
type 'Future' is not a subtype of type 'List'
Tried type-casting, but no help
On HomePage.dart
final getPost = NetworkFile().getPosts();
List posts;
void getPostsList() {
setState(() {
var res = getPost;
posts = res as List<dynamic>;
print(posts);
});
}
On Network.dart
class NetworkFile{
Future<dynamic> getPosts() async {
var response = await http.get('$kBlogURL' + 'posts?_embed');
Iterable resBody = await jsonDecode(response.body.toString());
return resBody;
}
}
You are decoding the response and its a List of type dynamic. There are few method to handle it. You can create a simple PODO class and cast/mapped to it. Or just do like below:
List posts = [];
void getPostsList() async {
final fetchedPosts = await NetworkFile().getPosts();
setState(() {
posts = fetchedPosts;
});
print(posts);
}
Here is a nice article about PODO.
final getPost = NetworkFile().getPosts();
Map posts;
void getPostsList() async {
var res = await getPost;
setState(() {
posts = res as Map<String, dynamic>;
print(posts);
});
}
class NetworkFile {
Future<dynamic> getPosts() async {
var response = await http.get('https://onetechstop.net/wp-json/wp/v2');
var resBody = await jsonDecode(response.body.toString());
return resBody;
}
}