NoSuchMethodError the method was called on Null - flutter

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.

Related

Flutter save data using http after get location

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

Position.longitude or latitude returns null and most of the time returns nothing

Here is the code , as I mentioned most of the time it returns nothing, but once it has returned null, the permission is enabled and nothing wrong with it.
class _LoadingScreenState extends State<LoadingScreen> {
double latitude;
double longitude ;
#override
void initState() {
getLocation();
}
void getLocation() async{
Location location = new Location();
await location.getCurrentLocation();
latitude = (location.latitude);
longitude= (location.longitude);
getData();
}
void getData() async{
http.Response response = await http.get(Uri.parse('https://samples.openweathermap.org/data/2.5/weather?lat=$latitude&lon=$longitude &appid= $apiKey'));
if(response.statusCode == 200){
String data = response.body ;
var decodedData = jsonDecode(data);
// var longitude = decodedData["coord"]["lon"];
var weatherDescription = decodedData["weather"][0]["description"];
int id = decodedData["weather"][0]["id"];
double temp = decodedData["main"]["temp"];
String city = decodedData["name"];
print("hi");
print(id);
print(temp);
print(city);
print(latitude);
print(longitude);
}
else {
print(response.statusCode);
}
}
and here is the location class , the permission is enabled and nothing wrong with it.
import 'package:geolocator/geolocator.dart';
import 'package:flutter/material.dart';
class Location{
double latitude ;
double longitude ;
Future <void> getCurrentLocation() async{
// bool servicestatus = await Geolocator.isLocationServiceEnabled();
//
// servicestatus ? print("GPS service is enabled"): print("GPS service is disabled.");
try {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.low);
latitude = position.latitude;
longitude = position.longitude;
}
catch (exception){
print(exception);
}
}
}

how can i send data to server interval times

it's my code
class TrackingManager {
Location locate = new Location();
Future<Map<String, double>> trackOn() async {
LocationData getlocationdata = await locate.getLocation();
Map<String, double> locationdata = {};
locationdata['latitude'] = getlocationdata.latitude ?? 0;
locationdata['longitude'] = getlocationdata.longitude ?? 0;
return locationdata;
}
}
if controller(user) call TrackingManager and initialize object,
and use trackOn so Stores the location information of the current user.
class LocateApiRequest {
final _networkManager = NetworkManager();
final _trackingManager = TrackingManager();
Future transmit(String accessToken) async {
final locationdata = await _trackingManager.trackOn();
final response = await _networkManager
.send(ApiRequestFactory.transmit(locationdata, accessToken));
final statusCode = response.statusCode;
if (statusCode == 200) {
final responseBody = jsonDecode(response.body);
return responseBody;
}
throw statusCode;
}
}
and Send the data to the server by requesting a post
But this action is carried out only once.
Starting with when a user clicks a specific button, I want to do this on the server with a regular time (background, foreground status is not important)
how can i solve it?I've thought about using a repeat statement, but this doesn't seem reasonable
using location callback
https://pub.dev/packages/location
location.onLocationChanged.listen((LocationData currentLocation) {
// call network api
// Use current location
});

The method '[]' was called on null. Receiver: null Tried calling: []("main")

I have this location.dart file
class Location {
double latitude;
double longitude;
Future<void> getCurrentLocation() async {
try {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.low);
latitude = position.latitude;
longitude = position.longitude;
} catch (e) {
print(e);
}
}
}
in another file I have
void getLocationData() 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&units=metric');
var weatherData = await networkHelper.getData();
}
If I do not put the await location.getCurrentLocation(); I get the error The method '[]' was called on null. My question is:
If I call the Location class in the second file, why do I also need to declare the getCurrentLocation() method of this class? If I call a class don't I also activate all of its methods?

How to Concatenate Strings & fetch data flutter

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