How to implement inheritance in dart? - oop

I want to have a class that inherits some properties from another class in Dart. What's the best way to do it?
This is my parent class :
class Photo {
final String id;
final String owner, server, secret, title;
final int farm, isfamily, ispublic, isfriend;
final String url;
Photo(
{this.id,
this.owner,
this.secret,
this.server,
this.farm,
this.title,
this.ispublic,
this.isfriend,
this.isfamily,
this.url});
factory Photo.fromJson(Map<String, dynamic> parsedJson) {
return new Photo(
id: parsedJson['id'],
owner: parsedJson['owner'],
secret: parsedJson['secret'],
server: parsedJson['server'],
farm: parsedJson['farm'],
title: parsedJson['title'],
ispublic: parsedJson['ispublic'],
isfriend: parsedJson['isfriend'],
isfamily: parsedJson['isfamily'],
url: parsedJson['url_m']);
}
}
This is the child class that i want to create:
class gPhoto : Photo //inherits Photo
{
string ownername;
string dateadded;
gPhoto(
{this.ownername,
this.dateadded
});
factory gPhoto.fromJson(Map<String, dynamic> parsedJson) {
return new Photo(
ownername: parsedJson['ownername'],
dateadded: parsedJson['dateadded'']);
}
Will this work? the factory from the Photo class will work with my new class or do i have to create a separate class for gPhoto in order to map the json?

You need to check out dart syntax which is a bit different from languages like C# using : for inheritance.
This is how you do it on your own:
class Photo {
final String id;
final String owner, server, secret, title;
final int farm, isfamily, ispublic, isfriend;
final String url;
Photo(
{this.id,
this.owner,
this.secret,
this.server,
this.farm,
this.title,
this.ispublic,
this.isfriend,
this.isfamily,
this.url});
factory Photo.fromJson(Map<String, dynamic> parsedJson) {
return new Photo(
id: parsedJson['id'],
owner: parsedJson['owner'],
secret: parsedJson['secret'],
server: parsedJson['server'],
farm: parsedJson['farm'],
title: parsedJson['title'],
ispublic: parsedJson['ispublic'],
isfriend: parsedJson['isfriend'],
isfamily: parsedJson['isfamily'],
url: parsedJson['url_m']);
}
}
class gPhoto extends Photo {
final String ownername;
final String dateadded;
gPhoto(
{id,
owner,
secret,
server,
farm,
title,
ispublic,
isfriend,
isfamily,
url,
this.ownername,
this.dateadded})
: super(
id: id,
owner: owner,
secret: secret,
server: server,
farm: farm,
title: title,
ispublic: ispublic,
isfamily: isfamily,
url: url);
factory gPhoto.fromJson(Map<String, dynamic> parsedJson) {
final photo = Photo.fromJson(parsedJson);
final ownername = parsedJson['ownername'];
final dateadded = parsedJson['dateadded'];
return gPhoto(
dateadded: dateadded,
ownername: ownername,
farm: photo.farm,
id: photo.id,
isfamily: photo.isfamily,
isfriend: photo.isfriend,
ispublic: photo.ispublic,
owner: photo.owner,
secret: photo.secret,
server: photo.server,
title: photo.title,
url: photo.url,
);
}
}

Related

SQLite error "near "#gmail": syntax error "flutter

Here's the error I get:
E/SQLiteLog(25090): (1) near "#gmail": syntax error .
It seems like there is a problem in email input.
I guess there is nothing wrong in the creating of database.
creating db:
class UsersTable {
static const String tableName = 'Users';
static const String id = 'id';
static const String email = 'email';
static const String createQuery = '''
CREATE TABLE IF NOT EXISTS $tableName (
$id integer primary key autoincrement,
$email text not null unique);''';
}
in model class:
class Users {
late final int id;
late String email;
Users({
required this.id,
required this.email,
});
Users.fromDb(Map<String, dynamic> map) {
id = map[UsersTable.id];
email = map[UsersTable.email];
}
}
in UserService class which I think is where the problem arise:
class UserService {
...
Future<Users> getOrCreateUser({
required String email,
bool setAsCurrentUser = true,
}) async {
try {
//we found the user
final user = await getUser(email: email);
if (setAsCurrentUser) {
_user = user;
}
return user;
} on CouldNotFindUser {
//we didn't find the user
final createdUser = await createUser(email: email);
if (setAsCurrentUser) {
_user = createdUser;
}
return createdUser;
} catch (e) {
rethrow;
}
}
Future<Users> getUser({required String email}) async {
await _ensureDbIsOpen();
final db = _getDatabaseOrThrow();
final results = await db.query(
UsersTable.tableName,
limit: 1,
where: 'email = ?',
whereArgs: [email.toLowerCase()],
);
if (results.isEmpty) {
throw CouldNotFindUser();
} else {
return Users.fromDb(results.first);
}
}
...}
in main class:
...
Widget build(BuildContext context) {
return FutureBuilder(
future: _userService.getOrCreateUser(email: userEmail),
builder: (context, snapshot) {
return Provider(
create: (ctx) => HomePageController(),
dispose: (ctx, HomePageController controller) =>
...
how can I solve this error?

Flutter SQFlite convert Class toJson()

I am building a SQFlite database for my app but I have a problem with the creation of my DB. Converting my class toJson() the code throws me the following errors:
Database file:
Future<Entries> create(Entries entries) async {
final db = await instance.database;
final id = await db.insert(tableFavs, entries.toJson());
}
Error (at entries.toJson()): A value of type 'Set' can't be returned from the method 'toJson' because it has a return type of 'Map<dynamic, dynamic>'.
Here is my class:
import 'package:flutter/material.dart';
const String tableFavs = 'favorites';
class EntryFields {
static late String id = '_id';
static late String name = '_name';
static late String navigation = '_navigation';
}
class Entries {
final int id;
final String name;
final Widget navigation;
Entries({
required this.id,
required this.name,
required this.navigation,
});
Map<Object> toJson() => {
EntryFields.id = id,
EntryFields.name = name,
EntryFields.navigation = navigation,
};
}
Does anyone knows how to fix this?

Unable to convert json response to list. Casting error

I am trying to convert my json response to list but getting the below error.
Json is fetched inside map ,but need to convert map to list and display in listview.
"_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>'"
Json Response
{"78":{"id":118,"first_name":"test","last_name":null,"email":"jignesh.test#gmail.com","phone":"","city":"null","state":"null","countrie_id":1,"location":"null","lat":"37.421998333333335","lng":"-122.08400000000002","image":"","role_id":3,"client_id":3,"coordinator_id":1,"sst_id":2,"created_at":"2018-10-08 10:59:18","updated_at":"2018-10-08 10:59:18","deleted_at":null,"status":0},
"79":{"id":119,"first_name":"Rahul test","last_name":null,"email":"rahul.test#gmail.com","phone":"","city":"null","state":"null","countrie_id":1,"location":"null","lat":"19.2284","lng":"72.85813","image":"","role_id":3,"client_id":3,"coordinator_id":1,"sst_id":2,"created_at":"2018-10-08 11:19:14","updated_at":"2018-10-08 11:19:14","deleted_at":null,"status":0},
"80":{"id":120,"first_name":"Customer Name","last_name":null,"email":"jjkkk#gmail.com","phone":"","city":"Mumbai","state":"Maharastra","countrie_id":1,"location":"virar","lat":"123","lng":"456","image":"images\/customer_image\/0hUSFUSqYAQTt57bVnnHjuQUOACECWzBOfJLWWa6.png","role_id":3,"client_id":1,"coordinator_id":1,"sst_id":2,"created_at":"2018-10-09 12:24:08","updated_at":"2018-10-09 14:03:07","deleted_at":null,"status":0},"status":"success","message":"List Fetched Successfully."}
Below is my Future method for calling post api method.
Future<PosModelData> posList(){
print('pos list api called');
return networkUtil.post("http://192.168.0.46/api/v1/poslist",body:{
"sstId":"2"
}).then((response){
if(response["status"]=="success"){
print("List fetched");
posLists=((response) as List).map((data)=>new PosModelData.fromJson(data)).toList();
// print(response.toString());
// print(posLists);
}
});
}
PosModel.dart
class PosModelData {
final String first_name;
final String last_name;
final String email;
PosModelData({this.first_name, this.last_name, this.email});
factory PosModelData.fromJson(Map json) {
return new PosModelData(
first_name: json['first_name'],
last_name: json['last_name'],
email: json['email'],
);
}
}
NetworkUtil.dart
Future<dynamic> post(String url, {Map header, body, encoding}) {
return http
.post(url, body: body, headers: header, encoding: encoding)
.then((http.Response response) {
final String resBody = response.body;
return jsonDecoder.convert(resBody);
});
}
I'm afraid your json string/response is not properly created.
In the same Map you have the status and then each element of your List so it's not possible to extract the List. You can reformat the server response and then get as shown in this code:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
String responseStr = '''
{
"status":"success",
"message":"List Fetched Successfully.",
"posts":
[
{"id":118,"first_name":"test","last_name":null,"email":"jignesh.test#gmail.com","phone":"","city":"null","state":"null","countrie_id":1,"location":"null","lat":"37.421998333333335","lng":"-122.08400000000002","image":"","role_id":3,"client_id":3,"coordinator_id":1,"sst_id":2,"created_at":"2018-10-08 10:59:18","updated_at":"2018-10-08 10:59:18","deleted_at":null,"status":0},
{"id":119,"first_name":"Rahul test","last_name":null,"email":"rahul.test#gmail.com","phone":"","city":"null","state":"null","countrie_id":1,"location":"null","lat":"19.2284","lng":"72.85813","image":"","role_id":3,"client_id":3,"coordinator_id":1,"sst_id":2,"created_at":"2018-10-08 11:19:14","updated_at":"2018-10-08 11:19:14","deleted_at":null,"status":0},
{"id":120,"first_name":"Customer Name","last_name":null,"email":"jjkkk#gmail.com","phone":"","city":"Mumbai","state":"Maharastra","countrie_id":1,"location":"virar","lat":"123","lng":"456","image":"images\/customer_image\/0hUSFUSqYAQTt57bVnnHjuQUOACECWzBOfJLWWa6.png","role_id":3,"client_id":1,"coordinator_id":1,"sst_id":2,"created_at":"2018-10-09 12:24:08","updated_at":"2018-10-09 14:03:07","deleted_at":null,"status":0}
]
}
''';
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<PosModelData> postList;
#override
void initState() {
super.initState();
getPosts();
}
Future<Null> getPosts() async {
// Your http logic
Map<String, dynamic> response = json.decode(responseStr);
if (response["status"] == "success") {
postList = ((response["posts"]) as List)
.map((data) => new PosModelData.fromJson(data))
.toList();
setState(() {});
}
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(),
body: Center(
child: postList != null ?
Column(
children: <Widget>[
new Text("${postList[0].first_name} ${postList[0].email}"),
new Text("${postList[1].first_name} ${postList[1].email}"),
new Text("${postList[2].first_name} ${postList[2].email}"),
],
) : CircularProgressIndicator(),
),
);
}
}
class PosModelData {
final String first_name;
final String last_name;
final String email;
PosModelData({this.first_name, this.last_name, this.email});
factory PosModelData.fromJson(Map json) {
return new PosModelData(
first_name: json['first_name'],
last_name: json['last_name'],
email: json['email'],
);
}
}
You assume that your JSON response is list of objects, while in fact it is a single object with keys that maps to PosModelData.
You should either change your server response to something like:
[
{
"id":118,
"first_name":"test",
"last_name":null,
...
},
{
"id":119,
"first_name":"Rahul test",
"last_name":null,
...
}
]
or change the way you parse JSON response.

How do generate child key for AngularFireDatabase?

I have pattern:
export class Items {
key: string;
item: string;
childItems: {key: string; item: string; };
}
And have some Service is generating parent key:
export class OptionService {
private dbPath = '/items';
itemsRef: AngularFireList<Items> = null;
constructor(private db: AngularFireDatabase) {
this.itemsRef = db.list(this.dbPath);
}
createItem(item: Items): void {
this.itemsRef.push(item);
}
How do may generate key in "childItems"? I need make unique key for this element when I will add property value. Please help me find resolve.

Spring Data Solr: how to set multiValue to false when declaring a field

I am playing around with Spring Data Solr with Schemaless Solr. There are some dots I am not able to connect: when and how are the schema fields being created?
The following page states
Automatic schema population will inspect your domain types whenever the applications context is refreshed and populate new fields to your index based on the properties configuration. This requires solr to run in Schemaless Mode.
Use #Indexed to provide additional details like specific solr types to use.
It also goes to show a curl request:
// curl ../solr/collection1/schema/fields -X POST -H 'Content-type:application/json'
However, when I run a simple example with field annotated with #Indexed, I do not see the /schema/fields API being called on SOLR. How are these fields created?
The reason I am asking is that they seem to be automatically created with multiValued=true. I did not see the #Indexed annotation taking multiValued as a parameter. How can I force Spring Data Solr to declare fields as non-multiValued when it creates them?
Now, all of this is really to resolve this exception I am seeing.
java.lang.IllegalArgumentException: [Assertion failed] - this argument is required; it must not be null
at org.springframework.util.Assert.notNull(Assert.java:115)
at org.springframework.util.Assert.notNull(Assert.java:126)
at org.springframework.data.solr.core.convert.MappingSolrConverter$SolrPropertyValueProvider.readValue(MappingSolrConverter.java:426)
at org.springframework.data.solr.core.convert.MappingSolrConverter$SolrPropertyValueProvider.readCollection(MappingSolrConverter.java:601)
at org.springframework.data.solr.core.convert.MappingSolrConverter$SolrPropertyValueProvider.readValue(MappingSolrConverter.java:440)
at org.springframework.data.solr.core.convert.MappingSolrConverter$SolrPropertyValueProvider.readValue(MappingSolrConverter.java:412)
at org.springframework.data.solr.core.convert.MappingSolrConverter$SolrPropertyValueProvider.getPropertyValue(MappingSolrConverter.java:395)
at org.springframework.data.solr.core.convert.MappingSolrConverter.getValue(MappingSolrConverter.java:206)
at org.springframework.data.solr.core.convert.MappingSolrConverter$1.doWithPersistentProperty(MappingSolrConverter.java:194)
at org.springframework.data.solr.core.convert.MappingSolrConverter$1.doWithPersistentProperty(MappingSolrConverter.java:186)
at org.springframework.data.mapping.model.BasicPersistentEntity.doWithProperties(BasicPersistentEntity.java:309)
at org.springframework.data.solr.core.convert.MappingSolrConverter.read(MappingSolrConverter.java:186)
at org.springframework.data.solr.core.convert.MappingSolrConverter.read(MappingSolrConverter.java:174)
at org.springframework.data.solr.core.convert.MappingSolrConverter.read(MappingSolrConverter.java:149)
at org.springframework.data.solr.core.SolrTemplate.convertSolrDocumentListToBeans(SolrTemplate.java:560)
at org.springframework.data.solr.core.SolrTemplate.convertQueryResponseToBeans(SolrTemplate.java:552)
at org.springframework.data.solr.core.SolrTemplate.createSolrResultPage(SolrTemplate.java:369)
at org.springframework.data.solr.core.SolrTemplate.doQueryForPage(SolrTemplate.java:300)
at org.springframework.data.solr.core.SolrTemplate.queryForPage(SolrTemplate.java:308)
at org.springframework.data.solr.repository.support.SimpleSolrRepository.findAll(SimpleSolrRepository.java:111)
at org.springframework.data.solr.repository.support.SimpleSolrRepository.findAll(SimpleSolrRepository.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at
My guess is that the exception is happening because values are being returned as a collection?
I tried to step through the code to understand what is happening. The field that is causing problem is "name", the value is [product-1]. The exception is happening when trying to unmarshall a solr document into a POJO.
First we go inside the following method:
private <T> T readValue(Object value, TypeInformation<?> type, Object parent) {
if (value == null) {
return null;
}
Assert.notNull(type);
Class<?> rawType = type.getType();
if (hasCustomReadTarget(value.getClass(), rawType)) {
return (T) convert(value, rawType);
}
Object documentValue = null;
if (value instanceof SolrInputField) {
documentValue = ((SolrInputField) value).getValue();
} else {
documentValue = value;
}
if (documentValue instanceof Collection) {
return (T) readCollection((Collection<?>) documentValue, type, parent);
} else if (canConvert(documentValue.getClass(), rawType)) {
return (T) convert(documentValue, rawType);
}
return (T) documentValue;
}
When calling this method, the value is a collection and the type is java.lang.String. This results in the if(documentValue instanceof Collection) being selected, which results into following method being executed:
private Object readCollection(Collection<?> source, TypeInformation<?> type, Object parent) {
Assert.notNull(type);
Class<?> collectionType = type.getType();
if (CollectionUtils.isEmpty(source)) {
return source;
}
collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class;
Collection<Object> items;
if (type.getType().isArray()) {
items = new ArrayList<Object>();
} else {
items = CollectionFactory.createCollection(collectionType, source.size());
}
TypeInformation<?> componentType = type.getComponentType();
Iterator<?> it = source.iterator();
while (it.hasNext()) {
items.add(readValue(it.next(), componentType, parent));
}
return type.getType().isArray() ? convertItemsToArrayOfType(type, items) : items;
}
In this method, we end up calling type.getComponentType(), which returns null and ultimately cause Assert.notNull() to fail.
What am I missing in all this?
My code is as follows. Launch and config class:
#Configuration
#ComponentScan
#EnableAutoConfiguration
#EnableSolrRepositories(schemaCreationSupport=true, basePackages = { "com.example.solrdata" }, multicoreSupport = true)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Model class:
#SolrDocument(solrCoreName = "collection1")
public class Product {
#Id
String id;
#Indexed
String name;
public Product(String id, String name) {
this.id = id;
this.name = name;
}
public Product() {
super();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}}
Repository:
public interface ProductRepository extends SolrCrudRepository<Product, String> {}
Test class:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(Application.class)
public class SolrProductRepositoryTest {
#Autowired
private ProductRepository repo;
#Before #After
public void setup(){
repo.deleteAll();
}
#Test
public void testCRUD() {
assertEquals(0, repo.count());
Product product = new Product("1","product-1");
repo.save(product);
assertEquals(1, repo.count());
Product product2 = repo.findOne(product.getId());
assertEquals(product2.getName(), product.getName());
}}
And finally, my POM:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-solr</artifactId>
</dependency>
</dependencies>
When using Solr 4.10 with the defaults unfortunately the JSONResponseWriter in solrconfig.xml uses text/pain as content type.
<queryResponseWriter name="json" class="solr.JSONResponseWriter">
<str name="content-type">text/plain; charset=UTF-8</str>
</queryResponseWriter>
This causes the content type negotiation of SolrSchemaRequest to silently fail and skip the schema update step - and solr default field type guessing kicks in at that place.
Setting content-type to application/json allows to add fields according to the bean definition.
#SolrDocument(solrCoreName = "collection1")
public static class SomeDomainType {
#Indexed #Id
String id;
#Indexed
String indexedStringWithoutType;
#Indexed(name = "namedField", type = "string", searchable = false)
String justAStoredField;
#Indexed
List<String> listField;
#Indexed(type = "tdouble")
Double someDoubleValue;
}
Before
{
responseHeader: {
status: 0,
QTime: 86
},
fields: [
{
name: "_version_",
type: "long",
indexed: true,
stored: true
},
{
name: "id",
type: "string",
multiValued: false,
indexed: true,
required: true,
stored: true,
uniqueKey: true
}
]
}
After Schema Upate
{
responseHeader: {
status: 0,
QTime: 1
},
fields: [
{
name: "_version_",
type: "long",
indexed: true,
stored: true
},
{
name: "id",
type: "string",
multiValued: false,
indexed: true,
required: true,
stored: true,
uniqueKey: true
},
{
name: "indexedStringWithoutType",
type: "string",
multiValued: false,
indexed: true,
required: false,
stored: true
},
{
name: "listField",
type: "string",
multiValued: true,
indexed: true,
required: false,
stored: true
},
{
name: "namedField",
type: "string",
multiValued: false,
indexed: false,
required: false,
stored: true
},
{
name: "someDoubleValue",
type: "tdouble",
multiValued: false,
indexed: true,
required: false,
stored: true
}
]
}