Parse nested json failed flutter - flutter

I have this json response that contains servicetype,vehiclemodels,accessories,working status as array but i cannot access any of the class,when i print print(obj); it just shows null
Json file
{
"success": true,
"message": "",
"data": {
"service_types": [
{
"id": 1,
"name": "Car Wash"
},
{
"id": 2,
"name": "Full Body Wash"
},
{
"id": 3,
"name": "Polishing"
},
{
"id": 4,
"name": "Engine Oil Checkup"
},
],
"vehicle_models": [
{
"id": 1,
"name": "SUV"
}
],
"accessories": [
{
"id": 2,
"name": "Mat Cover"
},
{
"id": 4,
"name": "Cash"
},
{
"id": 5,
"name": "Engine Room washing"
}
],
"working_statuses": [
{
"id": 0,
"name": "Registered"
},
{
"id": 1,
"name": "Work started"
},
{
"id": 2,
"name": "Work completed"
},
{
"id": 5,
"name": "Cancelled"
}
]
}
}
Code for extracting data
var response = await http.post(Uri.parse(Urls.DasboardData),
headers: {"Content-Type": "application/json"},
body: json.encode({
"vehicle_models": "",
"service_types": "",
"station_id":Station_id,
"accessories": "",
"working_statuses": "",
}));
Map<String, dynamic> value = json.decode(response.body);
var data = value['data'];
if (data.length > 0) {
for (int i = 0; i < data.length; i++) {
var obj = data[i];
print(obj);
var service_type_obj = obj['service_types'];
var vehicle_models_obj = obj['vehicle_models'];
var accessories_obj = obj['accessories'];
var working_statuses_obj = obj['working_statuses'];
DataList.add(GetAllModel(
service_type_obj['id'],
service_type_obj['name'],
vehicle_models_obj['id'],
vehicle_models_obj['name'],
accessories_obj['id'],
accessories_obj['name'],
working_statuses_obj['id'],
working_statuses_obj['name'],
));
}
setState(() {
print("UI UPDATED");
});
}
else
{
}
Model
class GetAllModel {
String service_type_id,
service_type_name,
vehicle_models_id,
vehicle_models_name,
accessories_id,
accessories_name,
working_statuses_id,
working_statuses_name;
GetAllModel(
this.service_type_id,
this.service_type_name,
this.vehicle_models_id,
this.vehicle_models_name,
this.accessories_id,
this.accessories_name,
this.working_statuses_id,
this.working_statuses_name,
);
}

The problem is at the time of iterating your information, the data size is 4, but this It contains 4 objects, therefore you will not be able to access data[i] because data[i] does not exist, if it exists data ['service_types'] which is a list and here if you could iterate the information that this contains object.
So to be able to access the information of your objects you must iterate them like this:
for (var i = 0; i < data['service_types'].length; i++) {
print(data['service_types'][i]);
}
and the same for the other objects.
An alternative to iterate:
for (var item in data.values) {
print(item);
}

You need to change these:
var service_type_obj = obj['service_types'];
var vehicle_models_obj = obj['vehicle_models'];
var accessories_obj = obj['accessories'];
var working_statuses_obj = obj['working_statuses'];
into this:
var service_type_obj = obj['service_types'][0];
var vehicle_models_obj = obj['vehicle_models'][0];
var accessories_obj = obj['accessories'][0];
var working_statuses_obj = obj['working_statuses'][0];
You're objects are located inside a list, to access them, you have to use an index, like[0].

Related

Dart - Convert Map of objects fetched via HTTP REST-API

For my Calendar i get the following data as JSON from the Backend (*JAVA-Type = Map<LocalDate, List<Event>>):
{
"2022-05-28": [
{
"id": 2,
"title": "Multi day Event",
"fromDate": "2022-05-27T12:22:03.873569",
"toDate": "2022-05-28T11:22:03.873569",
"room": {
"id": 1,
"name": "TestRoom",
},
"user": {
"id": 1,
"name": "Andi",
"city": "",
"email": "test#gmail.com",
},
"eventType": "sozial"
}
],
"2022-05-27": [
{
"id": 2,
"title": "Multi day Event",
"fromDate": "2022-05-27T12:22:03.873569",
"toDate": "2022-05-28T11:22:03.873569",
"room": {
"id": 1,
"name": "TestRoom",
},
"user": {
"id": 1,
"name": "Andi",
"city": "",
"email": "test#gmail.com",
},
"eventType": "sozial"
},
{
"id": 1,
"title": "Testevent",
"fromDate": "2022-05-27T11:21:04.573754",
"toDate": "2022-05-27T12:21:04.573754",
"room": {
"id": 1,
"name": "TestRoom",
},
"user": {
"id": 1,
"name": "Andi",
"city": "",
"email": "test#gmail.com",
},
"eventType": "normal"
}
],
}
My Event Class looks like:
Class Event {
int id;
String title;
DateTime fromDate;
DateTime toDate;
Room room;
User user;
String eventType;
}
Now i need the same structure i had in the Backend (Map<DateTime, <List<Event>>) for my Calendar widget and i have no real clue on how to do it. I know how to convert json data into an object if i get a list of an object, but how can i store the date as key of the resulting map?
My code by now:
Future<Map<DateTime, List<Event>>> getEvents(DateTime _fromDate, DateTime
_endDate) async {
String _from = _fromDate.toString().split('.').first;
String _end = _endDate.toString().split('.').first;
final response = await get('${_url}calendar/events/$_from/$_end',
headers: {HttpHeaders.authorizationHeader: 'Bearer $_bearer'});
if (response.status.hasError) {
return Future.error('${response.statusText}');
} else {
final parsed = jsonDecode(response.body);
return parsed;
}
}
You need to do something like that:
var json = {...}; // <-- json obj
// method to parse data to map with list Event
dynamic fromJson(Map<String, dynamic> json){
var map = new Map();
json.keys.forEach((key){
// key is the date
map[key] = json[key].map((e) => Event.fromJson(e)).toList(); // <- need to create a method fromJson in your Event class
});
return map;
}
(...)
class Event {
int id;
String title;
DateTime fromDate;
DateTime toDate;
Room room;
User user;
String eventType;
fromJson(Map<String, dynamic> json) => Event(...); // <- parse json to Event class
}

How would you find a certain map entry by a specific value?

Given the following map:
"user":
{
"userid":0,
},
"appData":{
"title":"Test",
"pages":1,
"posts":[
{
"postid":27979530,
"text":Test,
},
{
"postid":7732445,
"text":Test123,
},
{
"postid":9463254,
"text":Test568,
},
]
}
Given that map I want to try to find the entry for postid 7732445 so I can return the text value of Test123
What is the best way of doing something like that?
Given that
final Map<String, dynamic> json = {
"user": {
"userid": 0,
},
"appData": {
"title": "Test",
"pages": 1,
"posts": [
{
"postid": 27979530,
"text": "Test",
},
{
"postid": 7732445,
"text": "Test123",
},
{
"postid": 9463254,
"text": "Test568",
},
]
}
};
you could do this search by doing
json["appData"]["posts"]
.firstWhere(
(item) => item["postid"] == 7732445,
orElse: () => <String, Object>{},
)["text"]
Because of the orElse, this will return null if not found.

How to query objects from a set of key IDs in Firebase?

Consider the following data structure:
{
"company": {
"idCompany1": {
"data": {
"address": "",
"companyName": "Company 1",
"logo": "assets/Logo1.png",
"nit": "",
"phone": ""
}
},
"idCompany2": {
"data": {
"address": "",
"companyName": "Company 2",
"logo": "assets/Logo2.png",
"nit": "",
"phone": ""
}
},
"idCompany3": {
"data": {
"address": "",
"companyName": "Company 3",
"logo": "assets/Logo3.png",
"nit": "",
"phone": ""
}
}
},
"users": {
"idUser1": {
"data": "user1#test.com",
"companies": {
"idCompany1": true,
"idCompany3": true
}
},
"idUser2": {
"data": "user2#test.com",
"companies": {
"idCompany2": true
}
}
}
}
Basically what I need to do in the case of user1 is to read the data of the companies to which it belongs, this is Company 1 and Company 3. How can I do that?
The way I found, is by obtaining a list of IDs of those companies, which I have in listaIdEmpresas and then consulting each one through a forEach loop in the following way:
Future<List<EmpresaDatosModel>> cargarEmpresaDatosListado(List<String> listaIdEmpresas) async {
final List<EmpresaDatosModel> listaEmpresas = new List();
listaIdEmpresas.forEach((id) async {
Query resp = db.child('company/$id/data');
final snapshot = await resp.once();
final temp = EmpresaDatosModel.fromJson(Map<String,dynamic>.from(snapshot.value));
temp.idEmpresa = id;
listaEmpresas.add(temp);
print('${temp.companyName} up');
await resp.once().then((snapshot) {});
});
listaEmpresas.forEach((element) {print('Emp ${element.companyName}');});
return listaEmpresas;
}
However, this process is not efficient and I need to manage a delay for waiting the loop.
What would be the right way to do query data from a list of Ids directly?

Swashbuckle - Swagger execute button is not working

I am trying to integrate swagger in Asp.Net core 3.1 Web API using Swashbuckle.AspNetCore (5.5.1) with OAS3.
I am having one post method where I need multipart form data (two files and one string value) and for that I have applied below OperationFilter, because I don't want to specify any parameters at action level.
public class ComparePostParamTypes : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var listOfOutputFormats = new List<string> { "Rtf", "Doc", "DocX", "Pdf" };
var optionArray = new OpenApiArray();
optionArray.AddRange(listOfOutputFormats.Select(s => new OpenApiString(s)));
string documentOutputFormatText =
"The format to return";
switch (operation.OperationId)
{
case "File_Post":
operation.Parameters.Clear();
operation.Parameters = new List<OpenApiParameter>
{
new OpenApiParameter
{
Name = "file1", In = ParameterLocation.Query,
Required = true,
Description = "First Document",
Schema = new OpenApiSchema()
{
Type="string",
Format="binary"
}
},
new OpenApiParameter
{
Name = "file2", In = ParameterLocation.Query,
Required = true,
Description = "Second Document",
Schema = new OpenApiSchema()
{
Type="string",
Format="binary"
}
},
new OpenApiParameter
{Name = "outputFormat", In = ParameterLocation.Query, Description = documentOutputFormatText,
Schema = new OpenApiSchema()
{
Type="string",
Enum = optionArray,
Default = new OpenApiString("Rtf"),
}
}
};
break;
}
}
}
This is my controller endpoint
/// <summary>
/// POSTing two documents as a multipart/form-data.
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns>The result in the specified format (see outputFormat parameter)</returns>
/// <remarks>
/// Pass two document and output format</remarks>
/// <response code="200">OK</response>
/// <response code="500">Internal error</response>
/// <response code="403">Forbidden</response>
/// <response code="422">UnprocessableEntity</response>
/// <response code="503">ServiceUnavailable</response>
/// <response code="400">BadRequest</response>
[Produces("application/pdf", "application/msword", "application/zip")]
[Consumes("multipart/form-data")]
[ProducesResponseType(StatusCodes.Status200OK, Type = null)]
[ProducesResponseType(StatusCodes.Status500InternalServerError, Type = null)]
[ProducesResponseType(StatusCodes.Status403Forbidden, Type = null)]
[ProducesResponseType(StatusCodes.Status422UnprocessableEntity, Type = null)]
[ProducesResponseType(StatusCodes.Status503ServiceUnavailable, Type = null)]
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = null)]
[HttpPost(Name ="File_Post")]
public IActionResult Post()
{
var builBoundary = Request.GetMultipartBoundary();
return Ok(builBoundary);
}
Correct Swagger UI is rendered
Swagger UI
But when I clicked on execute button after attaching files nothing happened.
This is generated swagger JSON
{
"openapi": "3.0.1",
"info": {
"title": "Demo",
"version": "v1"
},
"paths": {
"/File": {
"post": {
"tags": [
"File"
],
"summary": "POSTing two documents as a multipart/form-data.",
"description": "Pass two document and output format",
"operationId": "File_Post",
"parameters": [
{
"name": "file1",
"in": "query",
"description": "First Document",
"required": true,
"schema": {
"type": "string",
"format": "binary"
}
},
{
"name": "file2",
"in": "query",
"description": "Second Document",
"required": true,
"schema": {
"type": "string",
"format": "binary"
}
},
{
"name": "outputFormat",
"in": "query",
"description": "The format to return",
"schema": {
"enum": [
"Rtf",
"Doc",
"DocX",
"Pdf"
],
"type": "string",
"default": "Rtf"
}
}
],
"responses": {
"200": {
"description": "OK"
},
"500": {
"description": "Internal error"
},
"403": {
"description": "Forbidden"
},
"422": {
"description": "UnprocessableEntity"
},
"503": {
"description": "ServiceUnavailable"
},
"400": {
"description": "BadRequest"
}
}
}
}
},
"components": { }
}
Please tell me what should I do to fix this.
I am able to fix this by updating OperationFilter
public class ComparePostParamTypes : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var listOfOutputFormats = new List<string> { "Rtf", "Doc", "DocX", "Pdf" };
var optionArray = new OpenApiArray();
optionArray.AddRange(listOfOutputFormats.Select(s => new OpenApiString(s)));
string documentOutputFormatText =
"The format to return";
switch (operation.OperationId)
{
case "File_Post":
var multipartBodyPost = new OpenApiMediaType
{
Schema = new OpenApiSchema
{
Type = "object",
Properties =
{
["file1"] = new OpenApiSchema
{
Description = "First Document",
Type = "string",
Format = "binary"
},
["file2"] = new OpenApiSchema
{
Description = "Second Document",
Type = "string",
Format = "binary"
},
["outputFormat"] = new OpenApiSchema
{
Description = documentOutputFormatText,
Type = "string",
Enum = optionArray,
Default = new OpenApiString("Rtf"),
},
},
Required = { "file1", "file2" }
}
};
operation.RequestBody = new OpenApiRequestBody
{
Content =
{
["multipart/form-data"] = multipartBodyPost
}
};
break;
}
}
}
I more details, check this link https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1782

Flutter return array from response from server

in this part of my code await webApi.getKeywords(); return array which that can get from server, now when i try to return that i get error:
type 'List<dynamic>' is not a subtype of type 'String'
get data from server code:
Future<List<KeywordsResponse>> _getKeywords(BuildContext context) async {
try {
final webApi = Provider.of<WebApi>(context);
final response = await webApi.getKeywords();
List<KeywordsResponse> list = List();
if (response.statusCode == 200) {
list = (json.decode(response.body) as List)
.map((data) => new KeywordsResponse.fromJson(data))
.toList();
return list;
} else {
throw Exception('Failed to load photos');
}
} catch (error) {
print(error);
return null;
}
}
KeywordsResponse class:
#JsonSerializable(nullable: true)
class KeywordsResponse{
#JsonKey(name:'id')
final int id;
#JsonKey(name:'title')
final String title;
#JsonKey(name:'description')
final String description;
KeywordsResponse(this.id, this.title, this.description);
factory KeywordsResponse.fromJson(Map<String, dynamic> json) => _$KeywordsResponseFromJson(json);
Map<String, dynamic> toJson() => _$KeywordsResponseToJson(this);
}
return of response.body:
[
{
"id": 1,
"user_id": 1,
"title": "asdasdasd",
"description": "asdasdasd",
"type": "post",
"slug": "asdasdad",
"featured_images": {
"images": {
"300": "/uploads/post_images/2019/300_1573573784.png",
"600": "/uploads/post_images/2019/600_1573573784.png",
"900": "/uploads/post_images/2019/900_1573573784.png",
"original": "/uploads/post_images/2019/1573573784.png"
},
"thumbnail": "/uploads/post_images/2019/300_1573573784.png"
},
"lang": "fa",
"visit": 0,
"categories": [
{
"id": 1,
"title": "aaaaaaa",
"lang": "fa",
"parent": 0,
"pivot": {
"contents_id": 1,
"content_categories_id": 1
}
}
]
},
{
"id": 2,
"user_id": 1,
"title": "asdasdasd",
"description": "asdadasd",
"type": "post",
"slug": "asdasdasda",
"featured_images": {
"images": {
"300": "/uploads/post_images/2019/300_1573573846.png",
"600": "/uploads/post_images/2019/600_1573573846.png",
"900": "/uploads/post_images/2019/900_1573573846.png",
"original": "/uploads/post_images/2019/1573573846.png"
},
"thumbnail": "/uploads/post_images/2019/300_1573573846.png"
},
"lang": "fa",
"visit": 0,
"categories": [
{
"id": 2,
"title": "bbbbbbbb",
"lang": "fa",
"parent": 0,
"pivot": {
"contents_id": 2,
"content_categories_id": 2
}
}
]
}
]
problem is on this line of code:
json.decode(response.body)
Try this:
list = List<KeywordsResponse>.from(response.body.map((x) => KeywordsResponse.fromJson(x)));