Converting object to an encodable object failed: Instance of 'Offset' - json

I'm trying to send Dart Offset points by encoding it to Json format using 'dart:convert' library.
I have gone through the documentation https://api.flutter.dev/flutter/dart-convert/jsonEncode.html.
The error I'm getting is for serializing the inbuilt classes.
The following JsonUnsupportedObjectError was thrown while handling a gesture:
Converting object to an encodable object failed: Instance of 'Offset'
How can i serialize inbuilt class like Offset and Paint class, is this the correct way to send the data to server?
TestData class contains Offset point and toJson() function
class TestData {
TestData(this.point);
Offset point;
toJson() {
return{
'point': point,
};
}
}
Encoder function
String jsonEncoder() {
Map testDataMap = this.testDataObj.toJson();
String jsonStringData = jsonEncode(testDataMap);
return jsonStringData;
}

I would return the JSON explicitly:
return { 'point': {dx: "$point.dx", dy: "$point.dy"}, };

Related

Android Kotlin Json Data parsing MVVM

I am new to android and currently I am learning kotlin I am using MVVM to get the remote data using Retrofit but I am not sure how to parse or implement the data got from JSON I am using json converter plugin to convert the json to data class. Below are my implementation i am not sure how to call or get the DATA from MyPostItems
This is the link I am using to get the JSON -> https://jsonplaceholder.typicode.com/posts -> As the arraylist does not have any name
I have two Data Class generated by JSON Coverter
class MyPost : ArrayList<MyPostItem>() -> you see here it does not even say Data Class and this is the base class i am calling using retrofit
#Entity(tableName = "Posts")
data class MyPostItem(
val body: String,
#PrimaryKey(autoGenerate = true)
val id: Int? = null,
val title: String,
val userId: Int
)
Here is my MVVM call from main Activity
viewModel.postData.observe(this, Observer { response->
when(response) {
is NetworkResource.Success -> {
binding.mainActivityProgressBar.visibility = View.GONE
response.data?.let { postResponse->
postAdapter.differ.submitList(postResponse) -> here i am getting the response but its the whole list not in the form of MyPostItems
}
}
is NetworkResource.Error -> {
binding.mainActivityProgressBar.visibility = View.GONE
response.message?.let { message ->
Log.e(TAG, "An error occured: $message")
}
}
is NetworkResource.Loading -> {
binding.mainActivityProgressBar.visibility = View.VISIBLE
}
}
})
}
P.S If anyone has resources or any study material on how to work with nested JSON object the link or reference to that would be very much apricated

Decoding json from google firebase rest api using Dart, not Flutter

I can retrieve a list of documents from a collection in a Cloud Firestore instance, in Firebase. The response contains the most verbose json I have ever seen. Here is a taste, ...
{
documents: [
{
name: projects/myprojectId/databases/(default)/documents/mycollection/0HC2spBFxEMNUc8VQLFg,
fields: {
name: {
stringValue: Jim's Bait Shop},
taxId: {
stringValue:
},
mailingAddress: {
mapValue: {
fields: {
streetAddress1: {
stringValue:
}
},
streetAddress2: {
stringValue:
},
state: {
stringValue: NC
},
city: {
stringValue: Boone
},
zipCode: {
stringValue:
}
}
}
}
},
createTime: 2020-08-31T19
:
54: 28.643464Z,
updateTime: 2020-09-01T02
:
35: 08.203028Z
},
{ ...
When trying to use jsonDecode, in dart:convert, it fails to de-serialize the json response into a collection of Dart objects.
'_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String'
And if I use cUrl instead of Dart, the json response looks just as verbose.
I'm using the FirebaseClient in "package:firebase/firebase_io.dart" to authenticate and read the collection.
I tried to build a "reviver" function but jsonDecode would not accept it so I'm not sure how I messed that up.
Anyway, I'm not seeing much guidance in the documentation on how to marshal this verbose json response into Dart objects. I suspect this server-side Dart is somewhat new territory. I want to avoid packages that require Flutter because I'm using a prebuilt docker image, with the Dart runtime preinstalled, on Google Cloud Run. (Truthfully, I've already tried a few Flutter packages for Firestore and a Flutter docker image.) I'll take any suggestions you have.
Below is the file I've been using for testing.
import 'package:firebase/firebase_io.dart';
import 'credentials.dart'; // borrowed from a SO post
import 'dart:convert';
const base = 'https://firestore.googleapis.com/v1/projects/';
void main() async {
// get private key...
final credential = await Credentials.fetch(); // string
final fbClient = FirebaseClient(credential);
final path = base + 'my_project_id/databases/(default)/documents/my_collection'
'?mask.fieldPaths=name&mask.fieldPaths=taxId&mask.fieldPaths=mailingAddress&orderBy=orgId';
final response = await fbClient.get(path);
print(response);
final orgs = jsonDecode(response); // unhandled exception
fbClient.close();
}
I think I might need to switch to a more sophisticated json deserializer package, and annotate my model classes to explicitly map this gnarly json to specific Dart class properties. But I have not yet seen a Dart package that supports such capabilities.
I have tried to use "json_serializable: 3.4.1" but failed to get code generation to work.
An online json validator is saying the response is malformed due to an apostrophe but can I trust that? Doubt I can escape special chars.
The error message says that response is not a String, it's a Map.
That means that Firebase has already parsed the JSON for you and returns the parsed structure.
You don't need to use jsonDecode, just final orgs = response;.
The solution was to stop using FirebaseClient, because it was not wrapping the name-value pairs in double quotation marks. Just use normal http instead.
import 'package:http/http.dart' as http;
const base = 'https://firestore.googleapis.com/v1/projects/';
void main() async {
//
final uri = base + 'myproject/databases/(default)/documents/mycollection' +
'?mask.fieldPaths=name&mask.fieldPaths=taxId&mask.fieldPaths=mailingAddress&orderBy=orgId&alt=json';
var response = await http.get(uri);
// print(response.body);
var json = jsonDecode(response.body)['documents'] as List;
List l = json.map((o) => MyModelClass.fromJson(o)).toList();
https://pub.dev/packages/http

Receive Map in ktor server using kotlinx.serialization

I have a Ktor server running with kotlinx.serialization as it's json (de)serializer
I send my Ktor a message like this one:
{
"Brick(partNumber=004229, partName=Sticker Sheet for Set 295-1, dataSource=Rebrickable, brickImage=null, categoryID=58)": 5
}
which is a pair of an Int and this class:
import kotlinx.serialization.Serializable
#Serializable
data class Brick(
val partNumber: String,
val partName: String,
val dataSource: String,
val brickImage: String?,
val categoryID: Int?
)
But I get this error
kotlinx.serialization.json.JsonDecodingException: Invalid JSON at 0: Expected '[, kind: MAP'
at kotlinx.serialization.json.internal.JsonReader.fail(JsonReader.kt:293)
Which to me means that kotlinx.serialization expects a different syntax for the map class. Which is odd to me. When I change the type into List> it throws the same exception but with LIST instead of MAP.
EDIT: Upon further inspection, it expects a [ instead of a { at the start of the line.
My (partial) application implementation
fun Application.module(testing: Boolean = false) {
install(ContentNegotiation) { serialization() }
routing {
route("user") {
route("brick") {
post {
call.request.queryParameters["userName"]
?.let { userRepository.login(it) } // Someone else is still working login nvm this
?.let { user ->
val bricks = call.receive<Map<Brick, Int>>() // This throws an error
userRepository.addBricks(user, bricks)
call.respond(HttpStatusCode.OK)
}
?: call.respond(HttpStatusCode.Unauthorized)
}
}
}
}
}
The android retrofit function that sends the class (using GSON):
#POST("/user/brick")
suspend fun setBricksAmounts(
#Query("userName")
userName: String,
#Body
brickAmounts: Map<Brick, Int>
)
I think using a class as a key does not work in kotlinx serialization
and it looks like that class is just serialized into a string to use it as key
Instead you can receive it as Map<String, Int>
and afterwards run
bricks.mapKeys { (jsonString, number) ->
Json(JsonConfiguration.Stable).parse(Brick.Serializer, jsonString)
}
or the equivalent jackson code if you want

How to convert file object to encodable json object in flutter?

Im trying to map profilePicture to a File object using dart , i have the profilePicture saved as IFormFile in the c# backend..
This is the mapping function and other functions in my ManageUserModel class:
Map<String, dynamic>toMap() {
return {
"profilePicture":profilePicture,
(other mappings)
}
}
List<ManageUserModel> fromJson(String jsonData) {
// Decode json to extract a map
final data = json.decode(jsonData);
return List<ManageUserModel>.from(
data.map((item) => ManageUserModel.fromJson(item)));
}
String toJson(ManageUserModel data) {
// First we convert the object to a map
final jsonData = data.toMap();
// Then we encode the map as a JSON string
return json.encode(jsonData);
}
Note that profilePicture is one of the ManageUserModel attributes and is of type File .
When the http update request is invoked via this method:
Future<String> updateUser(ManageUserModel data) async {
final response = await client.put("$baseUrl/Users",
headers: {"content-type": "application/json"},
body: toJson(data),
);
if (response.statusCode == 200) {
return "Success";
} else {
return "Fail";
}
}
i get this error:
E/flutter (10061): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Converting object to an encodable object failed: Instance of '_File'
Any help ?
From the error you've provided, it looks like you're trying to map '_File' object as a json.
E/flutter (10061): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Converting object to an encodable object failed: Instance of '_File'
That won't do since fromJson can only handle Maps. What you may want to consider is to store the file as an image URL, or as what have been previously mentioned in the comments - as base64.

How to convert NSObject class object into JSON in Swift?

I have
var contacts : [ContactsModel] = []
and
class ContactsModel: NSObject
{
var contactEmail : String?
var contactName : String?
var contactNumber : String?
var recordId : Int32?
var modifiedDate : String?
}
Now in contacts I'm having 6 values like
Now i want to convert contacts into JSON how can i ?
I tried
var jsonData: NSData?
do
{
jsonData = try NSJSONSerialization.dataWithJSONObject(contacts, options:NSJSONWritingOptions.PrettyPrinted)
} catch
{
jsonData = nil
}
let jsonDataLength = "\(jsonData!.length)"
But it crashes the app.
My issue is with manually converting in to a Dictionary one by one very time consuming it takes more than 5 minutes for 6000 records, So instead of that i want to convert directly model into JSON and send to server.
Your custom object can't be converted to JSON directly. NSJSONSerialization Class Reference says:
An object that may be converted to JSON must have the following properties:
The top level object is an NSArray or NSDictionary.
All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull.
All dictionary keys are instances of NSString.
Numbers are not NaN or infinity.
You might convert your object to a Dictionary manually or use some libraries like SwiftyJSON, JSONModel or Mantle.
Edit: Currently, with swift 4.0+, you can use Codable protocol to easily convert your objects to JSON. It's a native solution, no third party library needed. See Using JSON with Custom Types document from Apple.
If you just want a simple Swift object to JSON static function without any inheritance or dependencies to NSObject or NS-types directly. Check out:
https://github.com/peheje/JsonSerializerSwift
Full disclaimer. I made it. Simple use:
//Arrange your model classes
class Object {
var id: Int = 182371823
}
class Animal: Object {
var weight: Double = 2.5
var age: Int = 2
var name: String? = "An animal"
}
class Cat: Animal {
var fur: Bool = true
}
let m = Cat()
//Act
let json = JSONSerializer.toJson(m)
Currently supports standard types, optional standard types, arrays, arrays of nullables standard types, array of custom classes, inheritance, composition of custom objects.
You can use NSJSONSerialization for array when array contains only JSON encodable values (string, number, dictionary, array, nil)
first you need to create the JSON object then you can use it (your code is crashing because contact is not a JSON object!)
you can refere below link
https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSJSONSerialization_Class/#//apple_ref/doc/uid/TP40010946-CH1-SW9