When interacting with my function that initiate specs, flutter return me this error : "_CastError (Null check operator used on a null value)"
error code :
initSpecsTechs() async {
specs = await APIBike()
.getSpecsTechs(jwt: _user!.jwt, bikeId: favoriteBike!.id);
initBluetoothConnection();
initSliderAutomaticExtinctionValue();
initSliderAutomaticLockingValue();
initBackLightMode();
}
Full code of my page setting (first line contain the error code):
import 'package:myapp/api_bike.dart';
import 'package:myapp/api_user.dart';
import 'package:myapp/ux_components.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'blur_filter.dart';
class SettingsPage extends StatefulWidget {
@override
SettingsPageState createState() => SettingsPageState();
SettingsPage({required Key key}) : super(key: key);
}
class SettingsPageState extends State<SettingsPage>
with AutomaticKeepAliveClientMixin<SettingsPage> {
User? _user;
List<Bike> _bikes = [];
Bike? favoriteBike;
Specs? specs;
bool connectedByBluetooth = true;
double _currentSliderAutomaticExtinctionValue = 0;
double _currentSliderAutomaticLockingValue = 0;
bool theftAlertIsActive = true;
bool batteryAlertIsActive = true;
bool maintainAlertIsActive = true;
bool constantBackLight = true;
double spaceAfterSmallTitle = 15;
double spaceAfterWidget = 20;
//INIT FUNCTIONS
init() async {
await initUser();
await initBikes();
await initFavoriteBike();
await initSpecsTechs();
}
Future initUser() async {
final storage = new FlutterSecureStorage();
String mail = await storage.read(key: "mail") ?? "";
String password = await storage.read(key: "password") ?? "";
UserResponse userResponse = await APIUser()
.login(mail, password); //L'identifiant peut être le username ou le mail
User? user = userResponse.user;
if (user != null) {
setState(() {
_user = user;
});
}
return user;
}
initBikes() async {
if (_user != null) {
List<Bike> bikes = await APIBike().getAllUserBikes(jwt: _user!.jwt);
setState(() {
_bikes = bikes;
});
} else {
print("could not get the bikes call the user is null");
}
}
initFavoriteBike() async {
if (_bikes.length == 0) {
favoriteBike = null;
} else if (_bikes.length == 1) {
setState(() {
favoriteBike = _bikes.first;
});
} else {
Bike? favBike = await APIBike().getFavoriteBike(jwt: _user!.jwt);
if (favBike != null) {
setState(() {
favoriteBike = favBike;
});
} else {
print("PROBLEM : FAVORITE BIKE IS NULL");
}
}
}
initSpecsTechs() async {
specs = await APIBike()
.getSpecsTechs(jwt: _user!.jwt, bikeId: favoriteBike!.id);
initBluetoothConnection();
initSliderAutomaticExtinctionValue();
initSliderAutomaticLockingValue();
initBackLightMode();
}
initBackLightMode() {
if (specs != null) {
bool constantBackLightValue = false;
if (specs!.rearLight == "fixed") {
constantBackLightValue = true;
}
setState(() {
constantBackLight = constantBackLightValue;
});
} else {
print("Fake value used for initBackLightMode");
}
}
initTheftAlertIsActive() {
if (specs != null) {
setState(() {
theftAlertIsActive = specs!.theftAlarm;
});
} else {
print("Fake value used for initStealAlertIsActive");
}
}
initBatteryAlertIsActive() {
if (specs != null) {
setState(() {
batteryAlertIsActive = specs!.batteryAlarm;
});
} else {
print("Fake value used for initBatteryAlertIsActive");
}
}
initMaintenanceAlertIsActive() {
if (specs != null) {
setState(() {
maintainAlertIsActive = specs!.maintenanceAlarm;
});
} else {
print("Fake value used for initMaintenanceAlertIsActive");
}
}
initBluetoothConnection() {
//If this value is false then the page is all grey with nothing active
setState(() {
connectedByBluetooth = true;
});
}
initSliderAutomaticExtinctionValue() {
if (specs != null) {
double sliderValue = 0;
if (specs!.automaticSwitchOff == 0) {
sliderValue = 4;
} else if (specs!.automaticSwitchOff == 5) {
sliderValue = 0;
} else if (specs!.automaticSwitchOff == 10) {
sliderValue = 1;
} else if (specs!.automaticSwitchOff == 15) {
sliderValue = 2;
} else if (specs!.automaticSwitchOff == 20) {
sliderValue = 3;
} else {
//If there is a problem (it is not suppose to happen, we set it to never)
sliderValue = 0;
}
setState(() {
_currentSliderAutomaticExtinctionValue = sliderValue;
});
} else {
print("Fake value used for initSliderAutomaticExtinctionValue");
}
}
initSliderAutomaticLockingValue() {
if (specs != null) {
double sliderValue = 0;
if (specs!.automaticLocking == 0) {
sliderValue = 4;
} else if (specs!.automaticLocking == 1) {
sliderValue = 0;
} else if (specs!.automaticLocking == 3) {
sliderValue = 1;
} else if (specs!.automaticLocking == 5) {
sliderValue = 2;
} else if (specs!.automaticLocking == 10) {
sliderValue = 3;
} else {
//If there is a problem (it is not suppose to happen, we set it to never)
sliderValue = 0;
}
setState(() {
_currentSliderAutomaticLockingValue = sliderValue;
});
} else {
print("Fake value used for initSliderAutomaticLockingValue");
}
}
@override
void initState() {
super.initState();
init();
}
//UPDATE FUNCTIONS
updateRearLightValue(String newValue) async {
//TODO change the value on the bike by BLE
bool operationSucceed = await APIBike().updateSpecsTechs(
jwt: _user!.jwt,
bikeId: favoriteBike!.id,
specToUpdate: "rear_light",
newSpecValue: newValue);
if (operationSucceed) {
print("Rear light value updated successfully");
} else {
print("Error: rear light value didn't update correctly");
}
return operationSucceed;
}
updateAutomaticShutDownValue(double sliderValue) async {
//TODO change the value on the bike by BLE
int newValue = 0; // is also the value for never
if (sliderValue == 0) {
newValue = 5;
} else if (sliderValue == 1) {
newValue = 10;
} else if (sliderValue == 2) {
newValue = 15;
} else if (sliderValue == 3) {
newValue = 20;
} //else the new value is 0 which is never
bool operationSucceed = await APIBike().updateSpecsTechs(
jwt: _user!.jwt,
bikeId: favoriteBike!.id,
specToUpdate: "automatic_switch_off",
newSpecValue: newValue);
if (operationSucceed) {
print("Automatic switch off value updated successfully");
} else {
print("Error: Automatic switch off value didn't update correctly");
}
return operationSucceed;
}
updateAutomaticLockingValue(double sliderValue) async {
//TODO change the value on the bike by BLE
int newValue = 0; // is also the value for never
if (sliderValue == 0) {
newValue = 1;
} else if (sliderValue == 1) {
newValue = 3;
} else if (sliderValue == 2) {
newValue = 5;
} else if (sliderValue == 3) {
newValue = 10;
} //else the new value is 0 which is never
bool operationSucceed = await APIBike().updateSpecsTechs(
jwt: _user!.jwt,
bikeId: favoriteBike!.id,
specToUpdate: "automatic_locking",
newSpecValue: newValue);
if (operationSucceed) {
print("Automatic locking value updated successfully");
} else {
print("Error: Automatic locking value didn't update correctly");
}
return operationSucceed;
}
updateTheftAlertIsActive(bool newValue) async {
bool operationSucceed = await APIBike().updateSpecsTechs(
jwt: _user!.jwt,
bikeId: favoriteBike!.id,
specToUpdate: "theft_alarm",
newSpecValue: newValue);
if (operationSucceed) {
print("Theft alert value updated successfully");
} else {
print("Error: theft alert value didn't update correctly");
}
return operationSucceed;
}
updateBatteryAlertIsActive(bool newValue) async {
bool operationSucceed = await APIBike().updateSpecsTechs(
jwt: _user!.jwt,
bikeId: favoriteBike!.id,
specToUpdate: "battery_alarm",
newSpecValue: newValue);
if (operationSucceed) {
print("Battery alert value updated successfully");
} else {
print("Error: battery alert value didn't update correctly");
}
return operationSucceed;
}
updateMaintenanceAlertIsActive(bool newValue) async {
bool operationSucceed = await APIBike().updateSpecsTechs(
jwt: _user!.jwt,
bikeId: favoriteBike!.id,
specToUpdate: "maintenance_alarm",
newSpecValue: newValue);
if (operationSucceed) {
print("Maintenance alert value updated successfully");
} else {
print("Error: maintenance alert value didn't update correctly");
}
return operationSucceed;
}
/.../
And finally my api for the user :
import 'dart:collection';
import 'package:myapp/api_bike.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class ResponseWithError {
final bool result;
final String error;
ResponseWithError(this.result, this.error);
}
class APIUser {
//For dev
final String serverAddress =
"https://myadress.com/";
//TODO For production:
//final String serverAddress = "https://prodadress.com";
Future<ResponseWithError> createUser(
String firstname, String lastname, String email, String password) async {
var body =
"""{"username": "$firstname $lastname", "firstname": "$firstname", "lastname": "$lastname", "email": "$email", "password": "$password"}""";
var client = new http.Client();
var response = await client.post(
Uri.parse("$serverAddress/auth/local/register"),
body: body,
headers: {"Content-Type": 'application/json'});
if (response.statusCode == 200) {
print("USER CREATED");
print(response.body);
return ResponseWithError(true, "none");
} else {
print("Error " response.statusCode.toString());
print("Response Body");
print(response.body);
var responseBody = jsonDecode(response.body);
if (responseBody["message"][0]["messages"][0]["id"] != null) {
String errorMessageId = responseBody["message"][0]["messages"][0]["id"];
if (errorMessageId == "Auth.form.error.email.format") {
return ResponseWithError(false, "email format");
}
}
return ResponseWithError(false, "not known");
}
}
Future<UserResponse> login(String identifier, String password) async {
var body = """{"identifier": "$identifier", "password": "$password"}""";
var client = new http.Client();
var response = await client.post(Uri.parse("$serverAddress/auth/local"),
body: body, headers: {"Content-Type": 'application/json'});
if (response.statusCode == 200) {
//print("USER LOGGED IN");
final parsed = jsonDecode(response.body);
User user = User.fromJson(parsed);
UserResponse userResponse = UserResponse(user, true);
return userResponse;
} else {
//print("Error " response.statusCode.toString());
//print("Response Body");
//print(response.body);
var responseBody = jsonDecode(response.body);
if (responseBody["message"][0]["messages"][0]["id"] != null) {
String errorMessageId = responseBody["message"][0]["messages"][0]["id"];
if (errorMessageId == "Auth.form.error.confirmed") {
print("User not confirmed");
UserResponse userResponse = UserResponse(null, false);
return userResponse;
} else /*if(errorMessageId == "Auth.form.error.invalid")*/ {
print("email or password incorrect");
UserResponse userResponse = UserResponse(null, true);
return userResponse;
}
}
//Should not happen, but just in case
UserResponse userResponse = UserResponse(null, true);
return userResponse;
}
}
Future<bool> updateToken(String jwt, String notificationId) async {
var body = """{"notification_id": "$notificationId"}""";
var client = new http.Client();
var response = await client.put(Uri.parse("$serverAddress/users/token"),
body: body,
headers: {
"Content-Type": 'application/json',
'Authorization': 'Bearer $jwt'
});
if (response.statusCode == 200) {
print("NOTIFICATION TOKEN UPDATED");
return true;
} else {
print("Error " response.statusCode.toString());
print("Response Body");
print(response.body);
return false;
}
}
Future<bool> updateEmail(String jwt, String newEmail) async {
var confirmed = false;
var body = """{"email": "$newEmail", "confirmed": "$confirmed"}""";
var client = new http.Client();
var response = await client.put(Uri.parse("$serverAddress/users/me"),
body: body,
headers: {
"Content-Type": 'application/json',
'Authorization': 'Bearer $jwt'
});
if (response.statusCode == 200) {
print("EMAIL UPDATED");
return true;
} else {
print("Error " response.statusCode.toString());
print("Response Body");
print(response.body);
return false;
}
}
Future<bool> updateNames(
String jwt, String newFirstname, String newLastName) async {
var body =
"""{"username": "$newFirstname $newLastName", "firstname": "$newFirstname", "lastname": "$newLastName"}""";
var client = new http.Client();
var response = await client.put(Uri.parse("$serverAddress/users/me"),
body: body,
headers: {
"Content-Type": 'application/json',
'Authorization': 'Bearer $jwt'
});
if (response.statusCode == 200) {
print("NAMES UPDATED");
return true;
} else {
print("Error " response.statusCode.toString());
print("Response Body");
print(response.body);
return false;
}
}
Future<bool> updatePassword(String jwt, String newPassword) async {
var body = """{"password": "$newPassword"}""";
var client = new http.Client();
var response = await client.put(Uri.parse("$serverAddress/users/me"),
body: body,
headers: {
"Content-Type": 'application/json',
'Authorization': 'Bearer $jwt'
});
if (response.statusCode == 200) {
print("PASSWORD UPDATED");
return true;
} else {
print("Error " response.statusCode.toString());
print("Response Body");
print(response.body);
return false;
}
}
Future<bool> sendConfirmationCode(String email) async {
var body = """{"email": "$email"}""";
var client = new http.Client();
var response = await client.post(
Uri.parse("$serverAddress/auth/send-email-confirmation"),
body: body,
headers: {"Content-Type": 'application/json'});
if (response.statusCode == 200) {
print("EMAIL SENT to $email");
return true;
} else {
print("Error " response.statusCode.toString());
print("Response Body");
print(response.body);
return false;
}
}
Future<bool> verifyEmail(String email, String code) async {
var body = """{"email": "$email", "confirmation": "$code"}""";
var client = new http.Client();
var response = await client.put(
Uri.parse("$serverAddress/auth/email-confirmation"),
body: body,
headers: {"Content-Type": 'application/json'});
if (response.statusCode == 200) {
print("EMAIL VERIFIED");
return true;
} else {
print("Error " response.statusCode.toString());
print("Response Body");
print(response.body);
return false;
}
}
Future<bool> passwordForgotten({required String email}) async {
var body = """{"email": "$email"}""";
var client = new http.Client();
var response = await client.post(
Uri.parse("$serverAddress/auth/forgot-password"),
body: body,
headers: {"Content-Type": 'application/json'});
if (response.statusCode == 200) {
return true;
} else {
print("Error passwordForgotten :" response.statusCode.toString());
print("Response Body");
print(response.body);
return false;
}
}
}
class UserResponse {
User? user;
bool userConfirmed;
UserResponse(this.user, this.userConfirmed);
}
class User {
final int id;
final String jwt;
final String username;
final String firstname;
final String lastname;
final String email;
final String provider;
final bool confirmed;
final bool? blocked;
final String? notificationId;
final String createdAt;
final String updatedAt;
final List<int>?
bikesId; //Here we just save the ids of the bikes linked to the user
final Subscription? subscription;
final Role role;
User({
required this.id,
required this.jwt,
required this.username,
required this.firstname,
required this.lastname,
required this.email,
required this.provider,
required this.confirmed,
required this.blocked,
required this.notificationId,
required this.createdAt,
required this.updatedAt,
required this.bikesId,
required this.subscription,
required this.role,
});
factory User.fromJson(Map<String, dynamic> json) {
if (json['user']['subscription'] != null) {
return User(
id: json['user']['id'] as int,
jwt: json['jwt'] as String,
username: json['user']['username'] as String,
firstname: json['user']['firstname'] as String,
lastname: json['user']['lastname'] as String,
email: json['user']['email'] as String,
provider: json['user']['provider'] as String,
confirmed: json['user']['confirmed'] as bool,
blocked: json['user']['blocked'] as bool?,
notificationId: json['user']['notification_id'] as String?,
createdAt: json['user']['created_at'] as String,
updatedAt: json['user']['updated_at'] as String,
bikesId: createBikesIdList(json['user']['bikes_id']),
subscription: Subscription(
id: json['user']['subscription']['id'],
name: json['user']['subscription']['name'],
createdAt: json['user']['subscription']['created_at'],
updatedAt: json['user']['subscription']['updated_at']),
role: Role(
id: json['user']['role']['id'],
name: json['user']['role']['name'],
description: json['user']['role']['description'],
type: json['user']['role']['type'],
));
} else {
return User(
id: json['user']['id'] as int,
jwt: json['jwt'] as String,
username: json['user']['username'] as String,
firstname: json['user']['firstname'] as String,
lastname: json['user']['lastname'] as String,
email: json['user']['email'] as String,
provider: json['user']['provider'] as String,
confirmed: json['user']['confirmed'] as bool,
blocked: json['user']['blocked'] as bool?,
notificationId: json['user']['notification_id'] as String?,
createdAt: json['user']['created_at'] as String,
updatedAt: json['user']['updated_at'] as String,
bikesId: createBikesIdList(json['user']['bikes_id']),
subscription: null,
role: Role(
id: json['user']['role']['id'],
name: json['user']['role']['name'],
description: json['user']['role']['description'],
type: json['user']['role']['type'],
));
}
}
describe() {
print("id : $id\njwt : $jwt");
}
}
class Role {
final int id;
final String name;
final String description;
final String type;
Role({
required this.id,
required this.name,
required this.description,
required this.type,
});
}
class Subscription {
final int id;
final String name;
final String createdAt;
final String updatedAt;
Subscription(
{required this.id,
required this.name,
required this.createdAt,
required this.updatedAt});
}
CodePudding user response:
Can you try like this? I think user or favoriteBike is null. You need to null check.
initSpecsTechs() async {
if(_user != null && favoriteBike != null){
specs = await APIBike()
.getSpecsTechs(jwt: _user!.jwt, bikeId: favoriteBike!.id);
initBluetoothConnection();
initSliderAutomaticExtinctionValue();
initSliderAutomaticLockingValue();
initBackLightMode();
}
}
CodePudding user response:
initSpecsTechs() async {
specs = await APIBike()
.getSpecsTechs(jwt: _user!.jwt, bikeId: favoriteBike!.id);
initBluetoothConnection();
initSliderAutomaticExtinctionValue();
initSliderAutomaticLockingValue();
initBackLightMode();
}
The "!" operator causes the exception instead use "?" like this
specs = await APIBike() .getSpecsTechs(jwt: _user?.jwt??'', bikeId: favoriteBike?.id??'');