Dart Null Coalescing not returning default value - firebase-realtime-database

I have a list of staff 4 of whom are external consultants so they have no department in our Firebase Realtime Database.
In a FirebaseAnimatedList I am listing staff in an employee directory.
In my model I am trying to deal with those null values to suppress the error:
A non-null String must be provided to a Text widget. flutter:
'package:flutter/src/widgets/text.dart': flutter: Failed assertion:
line 253 pos 10: 'data != null'
I have used the following to no avail:
department = snapshot.value['department'] ?? 'Managment',
department = snapshot.value['department'] ??= 'Managment',
department = snapshot.value['department']
? snapshot.value['department']
: 'Management',
Any suggestions for this Flutter beginner is appreciated.
UPDATED with solution -- this is my entire model:
import 'package:firebase_database/firebase_database.dart';
class Staff {
String key;
String avatar;
String badge;
int dbId;
String department;
String directLine;
String email;
String extension;
String firstName;
bool isOnline;
String lastName;
String location;
String name;
String status;
String title;
String uid;
Staff(
this.key,
this.avatar,
this.badge,
this.dbId,
this.department,
this.directLine,
this.email,
this.extension,
this.firstName,
this.isOnline,
this.lastName,
this.location,
this.name,
this.status,
this.title,
this.uid);
Staff.fromSnapshot(DataSnapshot snapshot)
: key = snapshot.key,
avatar = "https://files.uaminc.com/images/avatars/" +
snapshot.value['avatar'],
badge = snapshot.value['badge'],
dbId = snapshot.value['dbId'],
department = snapshot.value.containsKey('department')
? snapshot.value['department']
: 'Management',
directLine = snapshot.value['directLine'],
email = snapshot.value['email'],
extension = snapshot.value['extension'],
firstName = snapshot.value['firstName'],
isOnline = snapshot.value['isOnline'],
lastName = snapshot.value['lastName'],
location = snapshot.value['location'],
name = snapshot.value['name'],
status = snapshot.value['status'],
title = snapshot.value.containsKey('title')
? snapshot.value['title']
: 'Management',
uid = snapshot.value['uid'];
toJson() {
return {
"key": key,
"avatar": avatar,
"badge": badge,
"dbId": dbId,
"department": department,
"directLine": directLine,
"email": email,
"extension": extension,
"firstName": firstName,
"isOnline": isOnline,
"lastName": lastName,
"location": location,
"name": name,
"status": status,
"title": title,
"uid": uid,
};
} // end method
}

Related

Swagger shows extra parameters in request body

We are using springfox-swagger-ui and springfox-swagger2 of version 2.7.0.
A post api has the following signature :
#ApiOperation("Edits information about employees")
#PostMapping(path = "/employee/edit", headers = EndPoints.VERSION_1)
#ApiResponses(value = {
#ApiResponse(code = 409, message = "Data mismatch"),
#ApiResponse(code = 400, message = "Invalid data passed")
})
public ResponseEntity<Employee> manageEmployee(
#RequestHeader("employeeId") final String iEmployeeId,
#RequestBody(required = true) #Valid final Employee iEmployee)
The object employee is:
public class Employee implements Serializable {
private static final long serialVersionUID = -7315844547195801413L;
private String employeeName;
private Long employeeId;
private #Valid #NotNull List<Address> addresses;
// getter and setter methods
#Validated
public static class Address implements Serializable {
private static final long serialVersionUID = 6748945632164495934L;
private String addressId;
#ValidAddress
private String addressName;
//getter and setter methods
}
}
But the swagger shows the request body as :
{
"addresses": {
"addressId": "string",
"addressName": "string",
"permanentAddress": [
{
"addressId": "string",
"addressName": "string"
}
]
},
"employeeName": "string",
"employeeId": 0
}
The object permanentAddress is not present in my code.
How can this be resolved?
Before questioning why permantnAddress, I think it's more important to find out why addresses is an object of addressId, addressName, and a list of Address. Something doesn't look right in the JSON.
The Employee object looks like:
{
addresses: [
addressId: "string",
addressName: "string"
],
employeeName: "string",
employeeId: 0
}
permanentAddress is the correct object for List addresses

Flutter / GraphQL - Mutation with custom type as parameter

I'm new to flutter and graphQL and currently I'm integrating mutations into my app. So, I have the server side using some custom types defined in the schema, but I don't know how to specify them on the flutter side. Let's see some code:
input DiaryGroupPermission {
groupId: Int!
permission: Int!
}
input DiaryInsideCommunity {
communityId: Int!
permissions: [DiaryGroupPermission]!
}
createDiary(community: DiaryInsideCommunity, description: String, title: String!): Diary
But on the client I don't know how to specify the DiaryInsideCommunity inside the mutation.
I've tried something like this:
String createDiary = """
mutation CreateDiary(\$title: String!, \$description: String!, \$community: DiaryInsideCommunity) {
createDiary(
title: \$title,
description: \$description,
community: \$community
) {
id
}
)}""".replaceAll('\n', ' ');
And passing my runMutation as follows:
runMutation({
"title": _generalPage.title(),
"description": _generalPage.description(),
"community": {
"communityId": 1,
"permissions": _permissionPage.selectedGroups().map((group) {
return {
"groupId": group.id,
"permission": 1,
};
}).toList(),
}
});
Any idea? Can't find anything on google.
Love to see the community that is created around the graphql_flutter library.
class DiaryGroupPermission {
int groupId;
int permission;
DiaryGroupPermission.fromJson(Map json)
: groupId = json['groupId'],
permission = json['permission'];
}
class DiaryInsideCommunity {
int communityId;
List<DiaryGroupPermission> permissions;
DiaryInsideCommunity.fromJson(Map json)
: communityId = json['communityId'],
permissions = json['permissions']
.map<DiaryGroupPermission>((Map permisionJson) =>
DiaryGroupPermission.fromJson(permisionJson))
.toList();
}
class Diary {
String body;
Diary(dynamic value) : body = value.toString();
}
typedef Diary createDiaryFunction(
DiaryInsideCommunity community, String description, String title);
DiaryInsideCommunity community = DiaryInsideCommunity.fromJson({
'communityId': 1,
'permissions': [
{'groupId': 1, 'permission': 1}
]
});
Diary mutation(DiaryInsideCommunity community,
{String description, #required String title}) =>
Diary(community.permissions[0].groupId);
Diary mutationResult = mutation(community, description: "a", title: "b");
I implemented the types that you wanted to in dart and created a mockup mutation function to show you how to call it.
There is no easier way to do types in dart.
Cheers from the creator of this library,
Eus
Assuming you are using graphql_flutter,
You may specify it in variables
an example is say you have this definitions for a mutation
type Mutation {
createMeterReading(
createMeterReadingInput: CreateMeterReadingInput
): MeterReading }
your input type definition
input CreateMeterReadingInput {
reading: Float
companyId: Int
companyStaffId: Int
customerId: Int
readingDataType: String
latitude: Float
longitude: Float
masterMeterId: Int
analogMeterId: Int
type: String
editedStatus: String
base64Image: String
readingTime: String
}
In flutter have
final response = await client.value.mutate(MutationOptions(
variables: {
'createMeterReadingInput': {
'reading': double.parse(_meterReadingController.text),
'companyStaffId': _decodedToken["companyStaffId"],
'analogMeterId': waterMeter["analogMeterId"],
'type': "actual",
'base64Image': getBase64(),
'readingTime': timeNow,
'latitude': widget?.currentPosition?.latitude,
'longitude': widget?.currentPosition?.longitude
}
},
documentNode: gql(r"""
mutation createMeterReading($createMeterReadingInput:CreateMeterReadingInput ) {
createMeterReading(createMeterReadingInput: $createMeterReadingInput) {
meterReadingId
reading
companyId
companyStaffId
imageUrl
editedStatus
companyStaff{
firstName
}
}
}
"""),
));

Profile is returning null after login

I have developed separate class to call APIs. In that process I have developed separate class for Web API call, Model class and one login screen. From login screen I am calling API class and my login is successful from that. But I want to retrieve profile data from there.
Which is returning null to me.
For your reference here is the code for login Class code from where I calling API class
//Login Button
final loginButton = ButtonTheme(
minWidth: MediaQuery.of(context).size.width-40,
height: 50.0,
child: new RaisedButton(
color: blueColor,
onPressed: (){
foo();
},
child: Text('Log In',
style: styleLoginButton,
),
shape: new RoundedRectangleBorder(borderRadius: new BorderRadius.circular(30.0))
),
);
void foo() async{
print('foo called');
final profile = await LoginAPI().profileGetRequest();
print(profile.firstName);
}
API Class
class LoginAPI {
Future<Profile> profileGetRequest() async {
try {
String strUserName = "test#tester.ch";
String strPassword = "tester";
String basicAuth = 'Basic ' +
base64Encode(utf8.encode('$strUserName:$strPassword'));
String strURL = Config.API_URL + Config.PROFILE;
final response = await http.get(
strURL,
headers: {
"Authorization": basicAuth,
"Content-Type": "application/json"
},
);
if (response.statusCode == 200) {
final responseJson = json.decode(response.body);
return Profile.fromJson(responseJson);
}
else {
return Profile.fromError(json.decode(response.body));
}
} catch (exception) {
print('exception $exception');
return null;
}
}
}
Profile Model
class Profile{
final int userId;
final String firstName;
final String lastName;
final String gender;
Profile(
this.userId,
this.firstName,
this.lastName,
this.gender
);
//Profile when Error received
Profile.fromError(Map<String, dynamic> json):
userId = 0,
firstName = null,
lastName = null,
gender = null;
//Profile when No Error Received
Profile.fromJson(Map<String, dynamic> json):
userId = json['userId'],
firstName = json['firstName'],
lastName = json['lastName'],
gender = json['gender'];
}
Keys of your map is not matching you have to change your keys like this
firstName ---> firstname
lastName ---> lastname
use the code below
//Profile when No Error Received
Profile.fromJson(Map<String, dynamic> json):
userId = json['userId'],
firstName = json['firstname'],
lastName = json['lastname'],
gender = json['gender'];

Convert a class into JSON or List

How to convert this class into JSON or List?
class cliente {
int id;
String nome;
String apelido;
String sexo;
String status;
}
Edit
I'm changed my class and works fine to my case:
class client {
Map<String, dynamic> fields => {
"id": "",
"name": "",
"nickname": "",
"sex": "",
"status": "",
}
Then I use:
client.fields["id"] = 1;
client.fields["name"] = "matheus";
sqlite.rowInsert("insert into client(id, name)", client.fields.Keys.toList(), client.fields.Values.toList());
Just create a method inside your class and return a Map<String, dynamic>
class cliente {
int id;
String nome;
String apelido;
String sexo;
String status;
Map<String, dynamic> toJson() => {
'id': id,
'nome': nome,
'apelido': apelido,
'sexo': sexo,
'status': status,
};
}
And use it for example :
final dataObject = new client();
...fill your object
final jsonData = dataObject.toJson();
Also you can try using this package to avoid writing all of your fields : https://pub.dartlang.org/packages/json_serializable

Need help to parsing JSON in Flutter

I am trying to get data from the internet in Flutter.
But I am getting an error on JSON parsing.
Can anyone tell me what is the problem?
I am trying to get data from this URL
https://swapi.co/api/starships/
Example JSON
{
"count": 37,
"next": "https://swapi.co/api/starships/?page=2",
"previous": null,
"results": [
{
"name": "Executor",
"model": "Executor-class star dreadnought",
"manufacturer": "Kuat Drive Yards, Fondor Shipyards",
"cost_in_credits": "1143350000",
"length": "19000",
"max_atmosphering_speed": "n/a",
"crew": "279144",
"passengers": "38000",
"cargo_capacity": "250000000",
"consumables": "6 years",
"hyperdrive_rating": "2.0",
"MGLT": "40",
"starship_class": "Star dreadnought",
"pilots": [],
"films": [
"https://swapi.co/api/films/2/",
"https://swapi.co/api/films/3/"
],
"created": "2014-12-15T12:31:42.547000Z",
"edited": "2017-04-19T10:56:06.685592Z",
"url": "https://swapi.co/api/starships/15/"
},
]
}
Model class
class RestModel {
final String name;
final String model;
final String manufacturer;
final String cost_in_credits;
final String length;
final String max_atmosphering_speed;
final String crew;
final String passengers;
final String cargo_capacity;
final String consumables;
final String hyperdrive_rating;
final String MGLT;
final String starship_class;
final List films;
final String pilots;
final String created;
final String edited;
final String url;
RestModel(
{this.name,
this.model,
this.manufacturer,
this.cost_in_credits,
this.length,
this.max_atmosphering_speed,
this.crew,
this.passengers,
this.cargo_capacity,
this.consumables,
this.hyperdrive_rating,
this.MGLT,
this.starship_class,
this.films,
this.pilots,
this.created,
this.edited,
this.url});
factory RestModel.fromJson(Map<String, dynamic> json) {
return RestModel(
name: json["name"],
model: json["model"],
manufacturer: json["manufacturer"],
cost_in_credits: json["cost_in_credits"],
max_atmosphering_speed: json["max_atmosphering_speed"],
crew: json["crew"],
passengers: json["passengers"],
cargo_capacity: json["cargo_capacity"],
consumables: json["consumables"],
hyperdrive_rating: json["hyperdrive_rating"],
MGLT: json["MGLT"],
starship_class: json["starship_class"],
films: json["flims"],
pilots: json["pilots"],
created: json["created"],
edited: json["edited"],
url: json["url"],
);
}
}
and the Flutter code is:
final link = "https://swapi.co/api/starships/";
List<RestModel> list;
Future getData() async {
var res = await http
.get(Uri.encodeFull(link), headers: {"Accept":"application/json"});
if (res.statusCode == 200) {
var data = json.decode(res.body);
var rest = data["results"];
for (var model in rest) {
list.add(RestModel.fromJson(model));
}
print("List Size: ${list.length}");
}
}
The main problem is when it tries to fill data from JSON.
RestModel.fromJson(model)
so what I have to change to fix this problem.
Try to cast the data 'results' to List , like this :
var rest = data["results"] as List;
Updated
Now that we know the error log: "No static method 'fromJson' declared in class 'RestModel'"
It's because you are using a static method in this line:
list.add(RestModel.fromJson(model));
You must change the call in order to use the factory constructor, like this :
list.add(new RestModel.fromJson(model));

Resources