FormatException (FormatException: Invalid date format) - json

It seems that my string is not a valid format to parse the DateTime i can't seem to understand where the culprit is.
This happen from time to time when the app initiate the data.
error code :
initListOfUsageValues() async {
if (favoriteBike != null) {
int periodWanted;
if (displayedUsageType == "year") {
periodWanted = displayedYear;
} else if (displayedUsageType == "month") {
periodWanted = displayedMonth;
} else {
periodWanted = displayedWeek;
}
List<int> list = await APIBike().getUsageData(
jwt: _user!.jwt,
bikeId: favoriteBike!.id,
year: displayedYear,
duration: displayedUsageType,
periodWanted: periodWanted,
);
//The received list is in seconds so we need to convert it in minute
list = convertSecondsToMinute(list);
setState(() {
listOfUsageValues = list;
});
} else {
print("favoriteBike null in initListOfUsageValues");
//check if the alertdialog saying that there is no bike linked to this account yet has been displayed already or no
final storage = new FlutterSecureStorage();
String lastNoBikeAlertShowUp =
await storage.read(key: "last_no-bike-alert_show-up") ?? "";
//If there is more than 60 minutes since last show up, we show the alertdialog saying that there is no bike linked to this account yet, else we don't
DateTime lastNoBikeAlertShowUpDateTime =
DateTime.parse(lastNoBikeAlertShowUp);
var now = new DateTime.now();
int timeInMinuteSinceLastAlertShowUp =
now.difference(lastNoBikeAlertShowUpDateTime).inMinutes;
if (timeInMinuteSinceLastAlertShowUp > 60) {
await storage.write(
key: "last_no-bike-alert_show-up", value: now.toString());
showDialog(
context: context,
builder: (BuildContext context) {
return noBikeYetAlertDialog(context);
});
}
}
}
The error is trigered in this line :
DateTime lastNoBikeAlertShowUpDateTime =
DateTime.parse(lastNoBikeAlertShowUp);

lastNoBikeAlertShowUp is empty string. Because you see break on trow FormatException inside of date_time.dart
// set default date or check if it is not empty
String lastNoBikeAlertShowUp = await storage.read(key: "last_no-bike-alert_show-up") ?? "";
if(lastNoBikeAlertShowUp.isNotEmpty){
}

Related

Good use of refetch for ListView with graphql_flutter

This is my query
Query(
options: QueryOptions(
document: gql(query),
variables: {
'startIndex': startIndex,
'endIndex': startIndex + 50
},
fetchPolicy: FetchPolicy.cacheAndNetwork,
),
builder: (
QueryResult result, { VoidCallback refetch, FetchMore fetchMore }
)
{
if (result.data == null){
refetch();
print('data is null');
}
startIndex = repositories.length;
print(startIndex);
return ListView.builder();
everytime I reload the page, it is showing
result: null
when print(result);
Then I added refetch() if result is null. Now it is showing
Query is not refetch safe
I used graphql_flutter ^5.0.0

Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<Model>'

I am trying to parse Json data that I get from an online API but get the error mentioned in the title. I looked at similar questions but could not find a solution.
Here is the relevant code:
class Model {
final double a;
final double b;
final String s;
Model._({this.a, this.b, this.s});
factory Model.fromJson(Map<String, dynamic> json) {
return new Model._(
a: json['a'],
b: json['b'],
s: json['s'],
);
}
}
void fetchPairValue() async {
final response = await http.get('https://api.1forge.com/quotes?pairs=USD/TRY,EUR/USD,EUR/TRY,CAD/TRY,GBP/TRY,AUD/TRY,JPY/TRY,CHF/TRY,AED/TRY,USD/QAR,USD/BGN,DKK/TRY,USD/SAR,USD/CNY,USD/RUB,NOK/TRY,SEK/TRY'
'&api_key=KatWbQa9sDFmYQ25LmtAMlGau5xKSWIe');
if (response.statusCode == 200) {
// If the call to the server was successful, parse the JSON
List<Model> list = json.decode(response.body).map((data) => Model.fromJson(data))
.toList();
setState(() {
currencyPair[0][1] = round_to_4(list[0].b).toString();
currencyPair[0][2] = round_to_4(list[0].a).toString();
for (int i = 1; i < currencyPair.length; i++) {
if(list[i].s.startsWith('USD'))
{
currencyPair[i][1] = round_to_4(list[i].b/list[1].b).toString();
currencyPair[i][2] = round_to_4(list[i].a/list[1].a).toString();
}
else {
currencyPair[i][1] = round_to_4(list[i].b).toString();
currencyPair[i][2] = round_to_4(list[i].a).toString();
}
}
});
} else {
// If that call was not successful, throw an error.
throw Exception('Failed to load post');
}
}
Sample Json Data:
[{"p":1.21856,"a":1.22201,"b":1.2151,"s":"EUR/USD","t":1608934265255},{"p":7.5575,"a":7.5625,"b":7.5525,"s":"USD/TRY","t":1608908143931},{"p":9.26299,"a":9.27256,"b":9.25342,"s":"EUR/TRY","t":1608879625018},{"p":6.037513,"a":6.039437,"b":6.035589,"s":"CAD/TRY","t":1608933871214},{"p":10.297348,"a":10.316695,"b":10.278,"s":"GBP/TRY","t":1608879629130},{"p":5.7738,"a":5.7885,"b":5.7591,"s":"AUD/TRY","t":1608879564069},{"p":0.07303697,"a":0.07308529,"b":0.07298864,"s":"JPY/TRY","t":1608908143937},{"p":8.529457,"a":8.538269,"b":8.520645,"s":"CHF/TRY","t":1608879624835},{"p":2.057672,"a":2.059033,"b":2.056311,"s":"AED/TRY","t":1608908143934},{"p":3.6413,"a":3.642,"b":3.6405,"s":"USD/QAR","t":1608847204796},{"p":1.6069188,"a":1.61497,"b":1.5988675,"s":"USD/BGN","t":1608861813327},{"p":1.2452666,"a":1.2465531,"b":1.24398,"s":"DKK/TRY","t":1608879625024},{"p":3.752353,"a":3.755106,"b":3.7496,"s":"USD/SAR","t":1608879629251},{"p":6.5418,"a":6.5428,"b":6.5408,"s":"USD/CNY","t":1608909993197},{"p":74.06,"a":74.095,"b":74.025,"s":"USD/RUB","t":1608930021562},{"p":0.87736,"a":0.878167,"b":0.876553,"s":"NOK/TRY","t":1608847205092},{"p":0.917155,"a":0.918032,"b":0.916278,"s":"SEK/TRY","t":1608847203927}]
How to fix? Thanks.
You need to add the generic type to the map function:
List<Model> list = json
.decode(response)
.map<Model>((data) => Model.fromJson(data))
.toList();

How to get the values from json object which is in the form Future<String>?

I am using aws_ai plugin and the response is in the form of
instance of Future<String>
I read the response as given below. I need to access specific value from json with key "confidence", how do I access it?
Future main1() async {
File sourceImagefile; //load source image in this File object
String accessKey = "",
secretKey = "",
region = "" ;
RekognitionHandler rekognition = new RekognitionHandler(accessKey, secretKey, region);
if(sourceImagefile !=null && targetImagefile !=null) {
Future<String> labelsArray = rekognition.compareFaces(
sourceImagefile, targetImagefile);
print(labelsArray);
return labelsArray.toString();
}else{
return "Enter Image";}
}
___________________________________
(later in widget build:)
___________________________________
onpressed(){
main1().then((labelsArray){
print("json value is: "+labelsArray);
});
}
the current result is :
json value is: Instance of 'Future<String>'
thanks for the help!
The reason you are getting the Instance of 'Future<String>' as a result is you are not waiting for the future to return and just getting the Future<String> object back refer this for more details:
The below code should solve your problem:
Future<String> futureFunction() async {
RekognitionHandler rekognition = new RekognitionHandler(accessKey, secretKey, region);
if(sourceImagefile !=null && targetImagefile !=null) {
var labelsArray = await rekognition.compareFaces(
sourceImagefile, targetImagefile);
print(labelsArray);
return labelsArray.toString();
} else {
return "enter image";
}
}

System.Collections.Generic.List`1[System.String]" JSON error

I'm trying to use JSON and I was use PostMan to return Response
this error happent
System.Collections.Generic.List`1[System.String]"}
public ActionResult SendVFCode(string Phone_Number)
{
var jsonSerialiser = new JavaScriptSerializer();
string error = "";
var SearchData ="";
if (Phone_Number == null)
{
error = "Must enter your phone number";
}
else if ( (db.PhoneNumbers.Select(x =>x.Id).Count() < 0)
&& (db.Assistant.Select(x =>x.Id).Count()) < 0)
{
error = "There are no data or your account is not activated";
}
else
{
SearchData = db.PhoneNumbers.Include(x => x.Assistant)
.Where(x => x.PhoneNumber == Phone_Number
&& x.Assistant.IsActive == true).Select(xx =>xx.PhoneNumber).ToList().ToString();
}
json = new
{
err = error,
ResultSearchData = SearchData
};
return Content(jsonSerialiser.Serialize(json));
}
SearchData is not a string. Don't declare it as string and don't try to shove a string into it. It's a List (probably of type List<string> or whatever your Phonenumber type is).
var SearchData =""
Should be:
List<string> SearchData;
And your database call should end in .ToList(), not .ToList().ToString().
Note that ToList() followed with ToString() returns fully-qualified name of the list instead of the list contents, hence you should use List<string> to hold result strings (also the list must be instantiated first before used inside if-block). The correct setup should be like this:
public ActionResult SendVFCode(string Phone_Number)
{
var jsonSerialiser = new JavaScriptSerializer();
string error = "";
var SearchData = new List<string>(); // instantiate list of strings
var phoneCount = db.PhoneNumbers.Select(x => x.Id).Count();
var assistantCount = db.Assistant.Select(x => x.Id).Count();
if (Phone_Number == null)
{
error = "Must enter your phone number";
}
else if (phoneCount < 0 && assistantCount < 0)
{
error = "There are no data or your account is not activated";
}
else
{
// assign list from query results
SearchData = db.PhoneNumbers.Include(x => x.Assistant)
.Where(x => x.PhoneNumber == Phone_Number && x.Assistant.IsActive == true)
.Select(xx => xx.PhoneNumber).ToList();
}
var json = new
{
err = error,
ResultSearchData = SearchData
};
return Content(jsonSerialiser.Serialize(json));
}

Nancy OnError will not accept a Response object?

The Nancy documentation seems to say that Pipelines.OnError should return null - as opposed to BeforeResponse which allows both null and a Response object.
All the examples like this one and many code samples here on StackOverflow show a Response being returned in the OnError, just like in the BeforeRequest.
When I attempt to return an HTTPStatus string for the Pipelines.OnError, everything works OK!
But when I attempt to return a Response, I get a compiler error:
Operator '+=' cannot be applied to operands of type 'Nancy.ErrorPipeline' and 'lambda expression'
I'm emulating almost exactly the code in the Nancy example, except for the fact that mine is a TinyIocContainer while the example's is using a StructureMap container and a StructureMap derived bootstrapper
Here's my code:
const string errKey = "My proj error";
const string creationProblem = "Message creation (HTTP-POST)";
const string retrievalProblem = "Message retrieval (HTTP-GET)";
public void Initialize(IPipelines pipelines)
{
string jsonContentType = "application/json";
byte[] jsonFailedCreate = toJsonByteArray(creationProblem);
byte[] jsonFailedRetrieve = toJsonByteArray(retrievalProblem);
Response responseFailedCreate = new Response
{
StatusCode = HttpStatusCode.NotModified,
ContentType = jsonContentType,
Contents = (stream) =>
stream.Write(jsonFailedCreate, 0, jsonFailedCreate.Length)
};
Response responseFailedRetrieve = new Response
{
StatusCode = HttpStatusCode.NotFound,
ContentType = jsonContentType,
Contents = (stream) =>
stream.Write(jsonFailedRetrieve, 0, jsonFailedRetrieve.Length)
};
// POST - error in Create call
pipelines.OnError += (context, exception) =>
{
// POST - error during Create call
if (context.Request.Method == "POST")
return responsefailedCreate;
// GET - error during Retrieve call
else if (context.Request.Method == "GET")
return responseFailedRetrieve;
// All other cases - not supported
else
return HttpStatusCode.InternalServerError;
};
}
private byte[] toJsonByteArray(string plainString)
{
string jsonString = new JObject { { errKey, plainString } }.ToString();
byte[] result = Encoding.UTF8.GetBytes(jsonString);
return result;
}
I had the same problem and I found a nice approach to the problem: http://paulstovell.com/blog/consistent-error-handling-with-nancy.
you should override RequestStartup on the Bootstrapper, here my test code:
protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
{
pipelines.OnError.AddItemToEndOfPipeline((ctx, ex) =>
{
DefaultJsonSerializer serializer = new DefaultJsonSerializer();
Response error = new JsonResponse(ex.Message,serializer);
error.StatusCode = HttpStatusCode.InternalServerError;
return error;
});
base.RequestStartup(container, pipelines, context);
}