Flutter Save JSON Array to SharedPreferences - arrays

How to save JSON array into SharedPreferences?
I've tried some code like this below, but i got some error :
[ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: type
'Text' is not a subtype of type 'String'
for (var x = 0; x < dynamicwidget.length - 1; x++) {
_listOrder={
"id_product": dataJSON[x]["product_id"],
"order_count": dynamicwidget[x].controller.text,
};
}
String json = jsonEncode(_listOrder);
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString(categoryname, json);

I would recommend you to use something like this (local storage implementation) which is made for saving and loading JSON.
From the code snippet itself i can't tell you exactly what is causing this exception but basically everywhere a String is beeing expected but you provided an actual Text widget. It could be the categoryname variable. What kind of controller do you get from your dynamicWidget instance? Are you sure controller.text returns a String?
Another note: you are re-assigning _listOrder with every for loop instead of adding information. You have to use an empty array which will be filled with every loop.

Thanks all, for contributing this question.
I've solved this question and makes some change.
_listOrder.clear();
for (var x = 0; x < dynamicwidget.length; x++) {
int jml = int.parse(dynamicwidget[x].controller.text == ""? "0": dynamicwidget[x].controller.text);
if (jml > 0) {
_listOrder.add({
"id_product": dataJSON[x]["product_id"],
"order_count": dynamicwidget[x].controller.text,
});
}
}
if (_listOrder.length > 0) {
SharedPreferences prefs = await SharedPreferences.getInstance();
Map<String, dynamic> _collOrder = Map<String, dynamic>();
String sessjson = prefs.getString("orderlist");
if (sessjson != null) {
_collOrder = json.decode(sessjson);
_collOrder.remove(categoryname);
}
_collOrder[categoryname] = _listOrder;
prefs.setString("orderlist", json.encode(_collOrder));
}

Related

How to seach emoji with proper text via Entity Framework Core

Here is my code:
var emoji = "⭐";
var query = myContext.Products.Where(x => x.Name.Contains(emoji));
var queryString = query.ToQueryString();
var list = query.ToList();
Query returns all table records. If I replace contains to equal works great, but I have to search something like this:
"this is my emoji ⭐"
This is the SQL query:
DECLARE #__emoji_0 nvarchar(4000) = N'⭐'
SELECT [p].[Id], [p].[Name], [p].[Quantity]
FROM [Products] AS [p]
WHERE (#__emoji_0 LIKE N'') OR (CHARINDEX(#__emoji_0, [p].[Name]) > 0)
Is any way to do this in EF Core or raw SQL?
Your main issue is the fact that emojis and strings are represented differently.
Before you can search the emojis you will need to decide how are you gonna unify them both in search query and db.
First of all emojis are a pair of chars.What does that mean? Here as a quote from the Microsoft docs:
"🐂".Length = 2
s[0] = '�' ('\ud83d')
s[1] = '�' ('\udc02')
These examples show that the value of string.Length, which indicates the number of char instances, doesn't necessarily indicate the number of displayed characters. A single char instance by itself doesn't necessarily represent a character.
The char pairs that map to a single character are called surrogate pairs. To understand how they work, you need to understand Unicode and UTF-16 encoding.
Having this in mind I would go as follows:
Define a method which will convert emojis to a UTF16 string[] which will keep the two surrogate chars representation.
internal static string[] EmojiToUtf16Pair(string emoji)
{
string[] arr = new string[2];
for (int i = 0; i < emoji.Length; i++)
{
arr[i] = emoji[i].ToString();
}
return arr;
}
This could be use when you persist emojis in DB. Depending on how you decide to persist the emojis in DB some modification could be done for that method e.g. to return concatenated string or something like that.
I am not sure when, but for some reason you could use another method to do the reverse operation -> UTF16 to Emoji
internal static string UTF16PairToEmoji(string[] codes)
{
var test = string.Empty;
foreach (var i in codes)
{
test += i;
}
var result = test.ToString();
return result;
}
Here is all the code example:
class Program
{
static void Main()
{
var str = "🚴";
var utf16 = string.Join("",EmojiToUtf16Pair(str));
Console.WriteLine(utf16);
var testEmpoji = UTF16PairToEmoji(EmojiToUtf16Pair(str));
Console.WriteLine(testEmpoji);
}
internal static string[] EmojiToUtf16Pair(string emoji)
{
string[] arr = new string[2];
for (int i = 0; i < emoji.Length; i++)
{
arr[i] = emoji[i].ToString();
}
return arr;
}
internal static string UTF16PairToEmoji(string[] codes)
{
var test = string.Empty;
foreach (var i in codes)
{
test += i;
}
var result = test.ToString();
return result;
}
}
emoji ef-core db-query
You have to use like command
SELECT * FROM emoticon where emoji_utf like '👨🏫';
with EF in .net core
Emoticon emoticon=db_context.Emoticons.Where(a=>EF.Functions.Like(a.EmojiUtf,"%"+item.emojiString+"%" ) ).FirstOrDefault();

Unable to access first data item in JSON Array

I'm having trouble pulling a piece of data from a JSON array. I believe I've tried every answer from similar posts here but I'm missing something. I've imported the org.JSON library. Here is my JSON text:
{
"symbol":"AAPL",
"earnings":[
{
"actualEPS":2.34,
"consensusEPS":2.17,
"estimatedEPS":2.17,
"announceTime":"AMC",
"numberOfEstimates":10,
"EPSSurpriseDollar":0.17,
"EPSReportDate":"2018-07-31",
"fiscalPeriod":"Q3 2018",
"fiscalEndDate":"2018-06-30",
"yearAgo":1.67,
"yearAgoChangePercent":0.40119760479041916,
"estimatedChangePercent":0.29 940119760479045,
"symbolId":11
},
{
"actualEPS":2.73,
"consensusEPS":2.69,
...
...
}
]
I'm trying to read the first instance of "actualEPS", there are a total of four in the array. My code currently looks like this:
String jsonIn = sb.toString();
JSONArray earningsArray = new JSONArray(jsonIn);
double eps = 0;
for(int i = 0; i < earningsArray.length(); i++) {
JSONObject jObject = earningsArray.getJSONObject(i);
eps = jObject.getDouble("actualEPS");
} // end for loop
System.out.println("This is the first instance of EPS: " + eps);
The StringBuilder (sb) in the first line is my JSON and prints out correctly in the console just ahead of this block.
The stack trace shows the error in this line:
JSONArray earningsArray = new JSONArray(jsonIn);
The error I'm getting is
"A JSONArray text must start with '[' at 1 [character 2 line 1]"
I've never used JSON prior to now and am not sure what my error is exactly. I tried shortening the String going into the array to begin with just the array opening bracket but that didn't work either. I feel like I'm missing something simple. Where have I gone wrong?
You need to understand there are two types of datastructure in a JSON.
first is Object which always starts with '{' and ends with '}'
second is Array which always starts with '[' and ends with ']'
JsonArray is nothing but an array of JsonObject means a json array will always look like
"jsonarray":[
{
//json object
},
{
// json object
}
]
hope now you understand how json works
now come to your json
{ // jsonObjectParent Starts
"symbol":"AAPL",
"earnings":[ // jsonArray Starts
{ //jsonObject1 Starts
"actualEPS":2.34,
"consensusEPS":2.17,
"estimatedEPS":2.17,
"announceTime":"AMC",
"numberOfEstimates":10,
"EPSSurpriseDollar":0.17,
"EPSReportDate":"2018-07-31",
"fiscalPeriod":"Q3 2018",
"fiscalEndDate":"2018-06-30",
"yearAgo":1.67,
"yearAgoChangePercent":0.40119760479041916,
"estimatedChangePercent":0.29 940119760479045,
"symbolId":11
}, // jsonOject1 Ends
{ //jsonObject2
"actualEPS":2.73,
"consensusEPS":2.69,
...
...
}
] //jsonArray Ends
} //jsonObjectParent Ends
So here if you want to parse this json you have to first parse it in a jsonObject as you seen above
JsonObject jsonObjectParent = new JsonObject(jsonIn);
// here jsonobject contains json array so etract it like this
JsonArray jsonArray = jsonObjectParent.getJsonArray("earnings");
//now you can access the values here
JsonObject jsonObject1 = jsonArray.getJsonObject(0); // here 0 means first jsonObject in array if you want all you can make a loop here
string actualEps = jsonObject1.getDouble("actualEPS");
Hope now you understands the concept of how JSON Works
please let me know is this solution worked
Do this :
JSONObject json = new JSONObject(response);
JSONArray data = json.optJSONArray("earnings");
for (int i = 0; i < data.length(); i++) {
JSONObject jsonObject1 = data.getJSONObject(i);
Double actualEPS = jsonObject1.getDouble("actualEPS");
Double consensusEPS = jsonObject1.getDouble("consensusEPS");
Double estimatedEPS= jsonObject1.getDouble("estimatedEPS");
String announceTime = jsonObject1.getString("announceTime");
int numberOfEstimates = jsonObject1.getInt("numberOfEstimates");
Double EPSSurpriseDollar= jsonObject1.getDouble("EPSSurpriseDollar");
String EPSReportDate= jsonObject1.getString("EPSReportDate");
String fiscalPeriod= jsonObject1.getString("fiscalPeriod");
String fiscalEndDate= jsonObject1.getString("fiscalEndDate");
Double yearAgo= jsonObject1.getDouble("yearAgo");
Double yearAgoChangePercent= jsonObject1.getDouble("yearAgoChangePercent");
Double estimatedChangePercent = jsonObject1.getDouble("estimatedChangePercent");
int symbolId = jsonObject1.getInt("symbolId");
}
#Driver8, the JSON earninsArray is a single JSON object and not an array of JSON objects. Your basic idea here is alright everywhere excpet for just that line. Instead of instantiating a JSON array, instantiate a JSON OBJECT.
Should be something like this:
String jsonIn = sb.toString();
JSONObject earningsObject = new JSONObject(jsonIn);
JSONArray earningsArray = earningsObject.getJSONArray("earnings");
double eps = new double(earningsArray.length());
for (int i = 0; i < earningsArray.length(); i++) {
JSONObject j1 = earningsArray.getJSONObject(i);
eps[i] = j1.getDouble("actualEPS");
}
All the values of actualEPS will be stored as per their order in the array declared to store the EPS values.
Hope this helps.

Extracting Array inside a Property in Azure Stream Analytics

I have had no luck so far extracting certain values in a wide format out of a JSON string via a stream analytics job.
The JSON has the following format:
{"devicename":"demo","msgtime":"2018-04-13T11:00:00.0000000Z",
"payload":[{"Sensor":"one","Value":1.817,"Unit":"W"},
{"Sensor":"two","Value":0.481,"Unit":"W"},
{"Sensor":"three","Value":0.153,"Unit":"W"}]}}
I am trying to get it in the following format:
name one two three
demo 1.817 0.481 0.153
… … … …
I tried getting the values with "Cross APPLY GetPropertyValues(input)", but I can't get them in a wide format.
try code like below
SELECT
localInput.devicename,
udf.getValue('one', localInput.payload) as One,
udf.getValue('two', localInput.payload) as Two,
udf.getValue('three', localInput.payload) as Three
FROM localInput;
function main(identifier, arr) {
var result = null;
if (Object.prototype.toString.call(arr) == "[object Array]") {
for (i = 0; i < arr.length; i++) {
if (arr[i].type == identifier) {
result = arr[i].value;
}
}
}
return result;
}

array initialization in angular 2, Typescript

when I am initializing array globally (outside the method) its working fine. but when I am initializing the same array inside the method its throwing error unexpected token. you can see into code for location of array. this is array calculateResult[] = [];
Screenshot of the error
private log: string ='result';
private kw: string = 'kw';
private frame: number = 0;
public finalResult[] = [];
//here this array is working fine
calculateResult[] = [];
DisplayResult(){
//if i initialize this array here, it's throwing error
// calculateResult[] = [];
if(some_conditions_true){
alert();
this.log = '1SE0 070-2NC70' '\n';
this.kw = '.37' '\n';
this.frame = '71' '\n';
this.calculateResult[0] = this.log;
this.calculateResult[1] = this.kw;
this.calculateResult[2] = this.frame;
this.finalResult.push(this.calculateResult);
for(i=0;i < this.finalResult.length;i++){
console.log(this.finalResult[0][0]);
console.log(this.finalResult[0][1]);
}
}
The first declaration is considered as a class property, so it's correct.
The second one, is incorrect because it is inside the class method and thus should be either declared as
let calculateResult=[];
if you intend to declare a new array of that name,
either addressed as the class property declared above as
this.calculateResult = ...
So keep the first one: calculateResult = [];
If you keep it commented, this.calculateResult[0] will be undefined in the class method, you cannot refer to it.
You should initialize as
DisplayResult(){
this.calculateResult = [];
}

substring from an array as3 **Error #1009: Cannot access a property or method of a null object reference

I am trying to create a matching game where one object in the array hitBoxes is matched to one object in the array hitBoxes2. I have tried to convert the instance name into a string and then used the substring method to match the LAST number in the instance name, if its a match they win. Right now I'm getting the error
TypeError: Error #1009: Cannot access a property or method of a null
object reference. at MethodInfo-499()
I'm wondering if anyone can help me. Thanks!
var left:String;
var correct:MovieClip = new Correct;
var isClicked:Boolean = false;
var leftClicked:int = 0;
p3.nextPage.buttonMode = true;
p3.nextPage.addEventListener(MouseEvent.CLICK, nextPage);
function nextPage(MouseEvent):void{
removeChild(p3);
}
var hitBoxes:Array = [p3.a1, p3.a2, p3.a3, p3.a4, p3.a5, p3.a6, p3.a7, p3.a8];
var hitBoxes2:Array = [p3.b1, p3.b2, p3.b3, p3.b4, p3.b5, p3.b6, p3.b7, p3.b8];
for (var h:int = 0; h < hitBoxes.length; h++){
hitBoxes[h].buttonMode = true;
hitBoxes[h].addEventListener(MouseEvent.CLICK, matchingLeft);
}
for (var h2:int = 0; h2 < hitBoxes2.length; h2++){
hitBoxes2[h2].buttonMode = true;
hitBoxes2[h2].addEventListener(MouseEvent.CLICK, matchingRight);
}
function matchingLeft(e:MouseEvent):void{
var left = String(e.currentTarget.name);
isClicked = true;
trace(left);
}
function matchingRight(e:MouseEvent):void{
var right:String = String(e.currentTarget.name);
trace(right);
if(isClicked == true && left.substring(3,3) == right.substring(3,3)){
trace("matched");
}
}
According to your code variable "left" is null at matchingRight method, because matchingLeft uses its local variable with name "left", and top-level "left" still has its default value.
also String.substring method is used incorrectly:
var name:String="p3.a1";
trace(name.substring(3, 3)); // this will always output empty string ""
trace(name.substring(4, 5)); // this will output "1" string
in conclusion I'd advise to use array indices (integers) instead of strings when calculating "matched" condition, substring operation and string comparison are CPU intensive.

Resources