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?
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?
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.
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
}
]
}