compile time null check not enough while iterating thorugh map keys - dart

The resultMap[element] + 1 ?? 0; part is complaining that resultMap[element] might be null, suggesting me to use ! operator.Please suggest
class WordCount {
Map<String, int> countWords(String wordle) {
List<String> wordleCollections = wordle
.toLowerCase()
.split(RegExp(r",?[\s\t\n.,]"))
.where((element) => element.isNotEmpty)
.toList();
var resultMap = <String, int>{};
for (var element in wordleCollections) {
resultMap[element] = resultMap[element] + 1 ?? 0;
}
return resultMap;
}
}
void main(List<String> args) {
final wordCount = WordCount();
print(wordCount.countWords("Joe can\'t tell between app, apple and a."));
}

Move the the null-aware operator ?? imediately after the resultMap[element] access:
Map<String, int> countWords(String wordle) {
List<String> wordleCollections = wordle
.toLowerCase()
.split(RegExp(r",?[\s\t\n.,]"))
.where((element) => element.isNotEmpty)
.toList();
var resultMap = <String, int>{};
for (var element in wordleCollections) {
resultMap[element] = resultMap[element] ?? 0 + 1;
}
return resultMap;
}

Related

Dart append to file when i use transform in read text from file

in this simple code i can show all fetched ids when finished reading file and get id from text file, but i want to append this fetched id inside JsonObjectTransformer class, not finished reading file
Future<void> main() async {
final ids = await File('sample.json')
.openRead()
.transform(const Utf8Decoder())
.transform<dynamic>(JsonObjectTransformer())
.map((dynamic json) => json['id'] as String)
.toList();
print(ids); // [#123456, #123456]
}
class JsonObjectTransformer extends StreamTransformerBase<String, dynamic> {
static final _openingBracketChar = '{'.codeUnitAt(0);
static final _closingBracketChar = '}'.codeUnitAt(0);
#override
Stream<dynamic> bind(Stream<String> stream) async* {
final sb = StringBuffer();
var bracketsCount = 0;
await for (final string in stream) {
for (var i = 0; i < string.length; i++) {
final current = string.codeUnitAt(i);
sb.writeCharCode(current);
if (current == _openingBracketChar) {
bracketsCount++;
}
if (current == _closingBracketChar && --bracketsCount == 0) {
yield json.decode(sb.toString());
sb.clear();
}
}
}
/*for example this line*/
//new File('test.txt').writeAsStringSync(sb.toString(), mode: FileMode.APPEND);
}
}
how can i do that?
There are multiple ways to do this but a simple way is to change the JsonObjectTransformer like this:
class JsonObjectTransformer extends StreamTransformerBase<String, dynamic> {
static final _openingBracketChar = '{'.codeUnitAt(0);
static final _closingBracketChar = '}'.codeUnitAt(0);
#override
Stream<dynamic> bind(Stream<String> stream) async* {
final sb = StringBuffer();
var bracketsCount = 0;
final ioSink = File('test.txt').openWrite(mode: FileMode.append);
await for (final string in stream) {
for (var i = 0; i < string.length; i++) {
final current = string.codeUnitAt(i);
sb.writeCharCode(current);
if (current == _openingBracketChar) {
bracketsCount++;
}
if (current == _closingBracketChar && --bracketsCount == 0) {
final dynamic jsonObject = json.decode(sb.toString());
ioSink.writeln(jsonObject['id'] as String);
yield jsonObject;
sb.clear();
}
}
}
await ioSink.flush();
await ioSink.close();
}
}
A more clean solution (since we want some separate of concern) would be to make use of the Stream in your main to write the ID's as each object are parsed. An example how to do that would be:
Future<void> main() async {
final file = File('test.txt').openWrite(mode: FileMode.append);
final ids = <String>[];
await File('sample.json')
.openRead()
.transform(const Utf8Decoder())
.transform<dynamic>(JsonObjectTransformer())
.map((dynamic json) => json['id'] as String)
.forEach((id) {
file.writeln(id);
ids.add(id);
});
await file.flush();
await file.close();
print(ids); // [#123456, #123456]
}

Flutter FutureBuilder Not Updating

I have a Flutter FutureBuilder that needs to be updated with new data given by the user. However, the UI elements in the FutureBuilder do not update and still contain the old values. I have checked through print statements that the new data is correctly loaded. The issue seems to be with FutureBuilder rebuilding the widget when the new data is loaded. Any help is appreciated.
Future<List<PollItem>> fetchPost(String loc) async {
return new Future(() async {
final response = await http
.post(restip + '/getPosts',
body: {"data": loc});
if (response.statusCode == 200) {
print(response.body);
// If the call to the server was successful, parse the JSON
// This function adds json to list
PollItem.fromJson(json.decode(response.body));
// list is a list of posts gathered based on the string criteria
return list;
} else {
throw Exception('Failed to load polls');
}
});
}
class PollState extends State<Poll> {
TextEditingController textc = new TextEditingController();
static String dropDowntext = "City";
String _name = "Search";
final _names = [''];
Widget build(BuildContext context) {
print("dropdown"+dropDowntext);
textc.text = _name;
print(dropDowntext);
return FutureBuilder<List<PollItem>>(
future: fetchPost(dropDowntext),
initialData: [PollItem()],
builder: (context, snapshot) {
if (snapshot.hasData) {
print(snapshot.data[0].question);
});
}
Here is my global file:
List<PollItem> list = new List();
factory PollItem.fromJson(Map<String, dynamic> json) {
int len = json['length'];
if(listNum!=len) {
listNum = len;
list.clear();
for (int i = 0; i < len; i++) {
list.add(PollItem(
answer1: json[i.toString()]['answer1'],
location: json[i.toString()]['location']
)
);
}
}
}
You don't need to create a Future object :
Future<List<PollItem>> fetchPost(String loc) async {
final response = await http.post(restip + '/getPosts',body: {"data": loc});
if (response.statusCode == 200) {
print(response.body);
final data = json.decode(response.body);
int len = data['length'];
final List<PollItem> newList = List();
for (int i = 0; i < len; i++) {
newList.add(PollItem(
answer1: data[i.toString()]['answer1'],
location: data[i.toString()]['location']
)
);
}
print("new list size: ${newList.length}");
return newList;
} else {
throw Exception('Failed to load polls');
}
return null;
}

StreamBuilder throws dirty state

I am trying to fetch some data from the internet, store it to my sqlite database and display it on the screen using a ListView.
When I fetch the data for the first time everything works fine and I am able to see the data on the screen, the data is also inserted in the sqlite database, but when I reopen the app I get an error saying
flutter: The following NoSuchMethodError was thrown building StreamBuilder<StudentModel>(dirty, state:
flutter: _StreamBuilderBaseState<StudentModel, AsyncSnapshot<StudentModel>>#3f888):
flutter: The getter 'studentData' was called on null.
flutter: Receiver: null
flutter: Tried calling: studentData
Here is my model class
class StudentModel {
int status;
String msg;
StudentModelData studentModelData;
StudentModel({this.status, this.msg, this.studentModelData});
StudentModel.fromJson(Map<String, dynamic> json) {
status = json['status'];
msg = json['msg'];
studentModelData = json['data'] != null ? new StudentModelData.fromJson(json['data']) : null;
}
StudentModel.fromDb(Map<String, dynamic> parsedJson) {
status = parsedJson['status'];
msg = parsedJson['msg'];
studentModelData = parsedJson['data'] != null ? new StudentModelData.fromJson(parsedJson['data']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['status'] = this.status;
data['msg'] = this.msg;
if (this.studentModelData != null) {
data['data'] = this.studentModelData.toJson();
}
return data;
}
}
class StudentModelData {
int lastIndex;
List<StudentData> studentData;
StudentModelData({this.lastIndex, this.studentData});
StudentModelData.fromJson(Map<String, dynamic> json) {
lastIndex = json['lastIndex'];
if (json['studentData'] != null) {
studentData = new List<StudentData>();
json['studentData'].forEach((v) {
studentData.add(new StudentData.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['lastIndex'] = this.lastIndex;
if (this.studentData != null) {
data['studentData'] = this.studentData.map((v) => v.toJson()).toList();
}
return data;
}
}
class StudentData {
String studentId;
String studName;
String studProfilepic;
String studentEmail;
String studentMobile;
String courseName;
String classCode;
int minAvg;
int avg;
StudentData(
{this.studentId,
this.studName,
this.studProfilepic,
this.studentEmail,
this.studentMobile,
this.courseName,
this.classCode,
this.minAvg,
this.avg});
StudentData.fromJson(Map<String, dynamic> json) {
studentId = json['student_id'];
studName = json['stud_name'];
studProfilepic = json['stud_profilepic'];
studentEmail = json['student_email'];
studentMobile = json['student_mobile'];
courseName = json['course_name'];
classCode = json['class_code'];
minAvg = json['minAvg'];
avg = json['avg'];
}
StudentData.fromDb(Map<String, dynamic> parsedJson){
studentId = parsedJson['student_id'];
studName = parsedJson['stud_name'];
studProfilepic = parsedJson['stud_profilepic'];
studentEmail = parsedJson['student_email'];
studentMobile = parsedJson['student_mobile'];
courseName = parsedJson['course_name'];
classCode = parsedJson['class_code'];
minAvg = parsedJson['minAvg'];
avg = parsedJson['avg'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['student_id'] = this.studentId;
data['stud_name'] = this.studName;
data['stud_profilepic'] = this.studProfilepic;
data['student_email'] = this.studentEmail;
data['student_mobile'] = this.studentMobile;
data['course_name'] = this.courseName;
data['class_code'] = this.classCode;
data['minAvg'] = this.minAvg;
data['avg'] = this.avg;
return data;
}
}
Following is my repository class
class StudentDbProvider implements Source, Cache {
Database db;
void init() async {
print("database initialized");
Directory documentsDirectory = await getApplicationDocumentsDirectory();
final path = join(documentsDirectory.path, "students.db");
db = await openDatabase(path, version: 1,
onCreate: (Database newDb, int version) {
newDb.execute("""
CREATE TABLE STUDENTS(
id INTEGER PRIMARY KEY,
student_id TEXT,
stud_name TEXT,
stud_profilepic TEXT,
student_email TEXT,
student_mobile TEXT,
course_name TEXT,
class_code TEXT,
minAvg TEXT,
avg TEXT
)
""");
});
}
#override
Future<int> clear() {
return db.delete("STUDENTS");
}
#override
Future<StudentModel> fetchStudents(String disciplineId, String schoolId,
String year_id, String lastIndex) async {
print("PritishSawant${db==null}");
final maps =
await db.query("STUDENTS");
if (maps.length > 0) {
return StudentModel.fromDb(maps.first);
}
return null;
}
#override
Future<int> addStudent(StudentData studentData) {
return db.insert("STUDENTS", studentData.toJson(),
conflictAlgorithm: ConflictAlgorithm.ignore);
}
}
final studentDbProvider = StudentDbProvider();
Following is my bloc class
class StudentsBloc {
final _repository = Repository();
final _students = PublishSubject<StudentModel>();
Observable<StudentModel> get students => _students.stream;
fetchStudents(String disciplineId,String schoolId,String year_id,String lastIndex) async {
await studentDbProvider.init();
final student = await _repository.fetchStudents(disciplineId, schoolId, year_id, lastIndex);
_students.sink.add(student);
}
clearCache(){
return _repository.clearCache();
}
dispose(){
_students.close();
}
}
As far as I can understand the error must be occurring due to improper database initialisation but when I did the first network request everything was working fine and I did not get any error in the console and the database was also initialised. I am not able to understand why the error is occurring for the second time onwards?
I suppose you are calling snapshot.data.studentData in some part of your code.
On a stream builder, I tend to first do a null check
if (snapshot.data != null) {
// your code here
}
And then proceed to verify the data, else you can use a getter on a null data provided by the StreamBuilder
You should check snapshot!=null && snapshot.hasError to ensure your data is actually returned
if (snapshot!=null && !snapshot.hasError) {
// your code here
}

Getting question marks in service response in codenameone

I am calling service using ConnectionRequest class and if i'm getting result in English i'm able to display it but if i'm getting response in Hindi at that time getting as question marks(?) instead of Hindi text. and i'm using Devanagari Font to show the hindi text. is there any solution for this?
here is the code for how we are requesting?
adding parameters using Map like below.
Map<String, Object> map = new HashMap<String, Object>();
map.add("Key","Value");
map.add("Key1","Value1");
etc..
then passing this map object to requestService method.
private static Map<String, Object> requestService(Map<String, Object> data) {
Connection connection = null;
Dialog progress = new InfiniteProgress().showInifiniteBlocking();
try {
connection = new Connection(data);
NetworkManager networkManager = NetworkManager.getInstance();
networkManager.addToQueueAndWait(connection);
networkManager.setTimeout(600000);
if(connection.getResponseData() == null) {
return null;
}
} finally {
progress.dispose();
}
JSONParser jp = new JSONParser();
try {
Map<String, Object> result = jp.parseJSON(new InputStreamReader(new ByteArrayInputStream(connection.getResponseData()), "UTF-8"));
return result;
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
Connection Class:
private static class Connection extends ConnectionRequest {
private final static char escapeS[] = new char[] { '"', '\\', '/', '\b', '\f', '\n', '\r', '\t' };
private final static char escapeR[] = new char[] { '"', '\\', '/', 'b', 'f', 'n', 'r', 't' };
private Map<String, Object> data;
private Connection(Map<String, Object> data) {
this.data = data;
setFailSilently(true);
setPost(true);
setWriteRequest(true);
setContentType("application/json");
setUrl(serverUrl);
}
#Override
protected void buildRequestBody(OutputStream os) throws IOException {
String v = buildJSON(data);
if(shouldWriteUTFAsGetBytes()) {
os.write(v.getBytes("UTF-8"));
} else {
OutputStreamWriter w = new OutputStreamWriter(os, "UTF-8");
w.write(v);
}
}
private static String buildJSON(Map<String, Object> data) {
StringBuilder json = new StringBuilder();
buildJSON(data, json);
return json.toString();
}
#SuppressWarnings("unchecked")
private static void buildJSON(Map<String, Object> data, StringBuilder json) {
json.append('{');
boolean first = true;
Object value;
for(String key: data.keySet()) {
value = data.get(key);
if(value == null) {
continue;
}
if(first) {
first = false;
} else {
json.append(",");
}
json.append('"').append(key).append("\":");
if(value instanceof Map) {
buildJSON((Map<String, Object>) value, json);
} else if(value instanceof Collection) {
buildJSON((Collection<Map<String, Object>>)value, json);
} else {
if(value instanceof Long || value instanceof Integer || value instanceof Double
|| value instanceof Short || value instanceof Float) {
json.append(value);
} else if(value instanceof Boolean) {
json.append((Boolean)value ? "true" : "false");
} else {
json.append('"').append(escape(value)).append('"');
}
}
}
json.append('}');
}
private static void buildJSON(Collection<Map<String, Object>> data, StringBuilder json) {
json.append('[');
boolean first = true;
for(Map<String, Object> e: data) {
if(first) {
first = false;
} else {
json.append(",");
}
buildJSON(e, json);
}
json.append(']');
}
private static String escape(Object any) {
if(any == null) {
return "";
}
String s = any.toString();
if(s == null) {
return "";
}
for(int i = 0; i < escapeS.length; i++) {
s = replace(s, escapeS[i], escapeR[i]);
}
return s;
}
private static String replace(String s, char c, char r) {
int i = s.indexOf(c);
if(i < 0) {
return s;
}
return s.substring(0, i) + "\\" + r + replace(s.substring(i + 1), c, r);
}
}
please guide me to achieve this?
That means the result is encoded in a foreign language encoding and should be read using the correct hindi text encoding.

Using the generic type 'PagedList.StaticPagedList<T>' requires 1 type arguments

I am working on user roles using Asp.net MVC. I am stuck while working on Admin section. I have mentioned one question above and the second question is similar which is Using the generic type 'System.Collections.Generic.List' requires 1 type arguments
Here is my code.
public ActionResult Index(string searchStringUserNameOrEmail, string currentFilter, int? page)
{
try
{
int intPage = 1;
int intPageSize = 5;
int intTotalPageCount = 0;
if (searchStringUserNameOrEmail != null)
{
intPage = 1;
}
else
{
if (currentFilter != null)
{
searchStringUserNameOrEmail = currentFilter;
intPage = page ?? 1;
}
else
{
searchStringUserNameOrEmail = "";
intPage = page ?? 1;
}
}
ViewBag.CurrentFilter = searchStringUserNameOrEmail;
List col_UserDTO = new List();
int intSkip = (intPage - 1) * intPageSize;
intTotalPageCount = UserManager.Users
.Where(x => x.UserName.Contains(searchStringUserNameOrEmail))
.Count();
var result = UserManager.Users
.Where(x => x.UserName.Contains(searchStringUserNameOrEmail))
.OrderBy(x => x.UserName)
.Skip(intSkip)
.Take(intPageSize)
.ToList();
foreach (var item in result)
{
ExpandedUserDTO objUserDTO = new ExpandedUserDTO();
objUserDTO.UserName = item.UserName;
objUserDTO.Email = item.Email;
objUserDTO.LockoutEndDateUtc = item.LockoutEndDateUtc;
col_UserDTO.Add(objUserDTO);
}
// Set the number of pages
// Error appears here
var _UserDTOAsIPagedList =
new StaticPagedList
(
col_UserDTO, intPage, intPageSize, intTotalPageCount
);
return View(_UserDTOAsIPagedList);
}
catch (Exception ex)
{
ModelState.AddModelError(string.Empty, "Error: " + ex);
List col_UserDTO = new List(); // Error appears here
return View(col_UserDTO.ToPagedList(1, 25));
}
}
#endregion
`
StaticPagedList is generic. You need to supply the type of collection(for col_UserDTO), in your case List:
var _UserDTOAsIPagedList =
new StaticPagedList<List<ExpandedUserDTO>>
(
col_UserDTO, intPage, intPageSize, intTotalPageCount
);
See http://www.programering.com/a/MTN2gDNwATM.html
You may need to change List col_UserDTO references to List<ExpandedUserDTO> col_UserDTO
Use this instead
var _UserDTOAsIPagedList =
new StaticPagedList<ExpandedUserDTO>
(
col_UserDTO, intPage, intPageSize, intTotalPageCount
);

Resources