Extjs store store cuts the last digits of a bigint values - extjs

I usesd Extjs 7.4. When I load data into an extjs store, I have the problem that the last digits are truncated for bigint values.
It doesn't matter if the model field type is int or number. Bigint values ​​are only displayed correctly if the type is string. I can't use the field as a string in the idProperty of the data model. Does somebody has any idea.

Maybe it is a limit of javascript, not ExtJs. In fact if you try to create a new object with a bigint property you get some truncated number:
var record = {
numericValue: 9223372036854776807,
stringValue: "9223372036854775807"
};
console.log(record);
It prints:
{
numericValue: 9223372036854776000,
stringValue: "9223372036854775807"
}
---EDIT---
A solution could be to pass for the convert config of the BigInt field defined in the store's model. Note that your property should be initially read by the store as a string. Doing like this, the property will correctly store BigInt values:
Ext.define("MyStore",{
extend: "Ext.data.Store",
fields: [
{
name: "bigIntProp",
convert: function (value) {
return BigInt(value);
}
}
]
});
var store = new MyStore();
store.add({ bigIntProp: '9223372036854775807' });
// This correctly print the big int value now
console.log(store.getAt(0).get("bigIntProp"));

Related

Convert Image from Buffer to display in Frontend (Flutter)

I have a backend based on NodeJS and using mongodb as the database. Images with the field name photo is saved as object Type Buffer. I have successfully sent Images from the app using form data but I am not able to display the image in frontend.
This is the function used to get the data from API
Future<User> userWithId() async {
User result;
try {
final response = await http.get(
'api link',
headers: <String, String>{
'Authorization': 'Bearer $token',
},
);
if (response.statusCode == 200) {
result = User.fromJson(jsonDecode(response.body));
}
} catch (e) {
print(e.toString());
}
return result;
}
This is the fromJson function of the class User. The photo field here returns the image as buffer.
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['_id'] as String ?? "",
email: json['email'] as String ?? "",
// profilePhoto: json["photo"] ?? null,
// profilePhoto: base64.encode(jsonDecode(json["photo"])) ?? null,
);
}
This is the data from the photo field
This is the data from MongoDB database
For those who are facing this issue as well, this is a multi-part problem:
Converting List to List.
Using converted List to read/display image.
In OP's case, to get buffer List would be profilePhoto: json["photo"]["data"]["data"].
For step 1, To convert List to List:
List<dynamic> bufferDynamic = profilePhoto: json["photo"]["data"]["data"];
List<int> bufferInt = buffer.map((e) => e as int).toList();
For step 2 as some have already mention, use Image.memory class provided by Flutter.
Image.memory(Uint8List.fromList(bufferInt))
Hope this helps for those who need to read/display image from buffer. (:
you can use base64Decode method from dart:convert
store your image binary in string format:
factory User.fromJson(Map<String, dynamic> json) {
return User(
...
profilePhoto: json["photo"] ?? null,
...
);
}
and use the following code in UI:
Image.memory(base64Decode(user.profilePhoto))
also, don't forget to add an if statement to check if the photo is null or not
Hope, it helps
json['photo']['data']['data'];
By doing this you are getting this error List' is not a subtype of type 'String'. So may be your return type for profilePhoto is String. Change it to dynamic then try again.
Thanks to the great article bellow explaining about bytes in dart, you can convert your response data which is as List of integers, to Uint8List data type and pass it to Image.memory to render image.
Image.memory(Uint8List.fromList(// pass image data array here));
https://medium.com/flutter-community/working-with-bytes-in-dart-6ece83455721
Try like this
List<int> imageData = user.profilePhoto['data'] as List<int>
////
Image.memory(Uint8List.fromList(imageData));
Image type
You should modify your class User, currently you have something like:
class User {
final String id;
final String email;
final ? profilePhoto
}
I am not sure which type you are currently using but you need to change it accordingly to the data you get in your response. Your image is, in your computer, a list of bytes (uint8, meaning unsigned integer of 8 bits, so 1 byte), ranging from 0 to 255 in value (0 to 0xFF).
Images header
You can read about EXIF to understand better how the standard specifies the formats for images
Every JPEG file starts from binary value '0xFFD8', ends by binary value '0xFFD9'.
The first eight bytes of a PNG file always contain the following (decimal) values: 137 80 78 71 13 10 26 10
Fix
Change the type of your profilePhoto to Uint8List, full code:
class User {
final String id;
final String email;
String profilePhoto // I don't know which type you use
User({this.id, this.email, this.profilePhoto});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
id: json['_id'] as String ?? "",
email: json['email'] as String ?? "",
profilePhoto: json["photo"] ?? null,
);
}
}
And then load the image in your widget with Image.memory while being cautious as its value could be null:
return user.profilePhoto != null ? Image.memory(user.profilePhoto) : Container();
NB: Image.memory is a shorthand of an Image widget backed by MemoryImage.

Convert NUMERIC to VARCHAR using sequelize model

I have this NUMERIC(20) field on mssql and I'm trying do read it as a data type string to get the full number because int limits on javascript
code: {
type: DataTypes.STRING
}
But the returned value is a truncated INT
[ {code: 4216113112911594000 } ]
No matter what kind of data type choose it'll return as truncated int
The original values is 4216113112911594192. This is a java UUID
How can a convert this value to using model.findAll()
This is a already created table for another application and I'm trying to read it using sequelize
Here you go :
code: {
type: Sequelize.INTEGER , // <------ keep is as DB's datatype
get() { // <------ Use getter method to modify the output of query
return this.getDataValue('code').toString();
}
}
I think this might help you
model.findOne({
attributes: [[db.sequelize.literal('cast(`code` as varchar)'), 'code_string']] ,
where : { id : YOUR_ID }
}).then(data => {
console.log(data); // <------ Check your output here
})
I have not fully understood what you are trying to achieve.
Nor my code is tested.
Idea 1 : convert into float.
Idea 2 : Append any string alphabet to originial int value before sending to javascript.
The original values is 4216113112911594192.
So the string become 'A'+'4216113112911594192'='A4216113112911594192'
Now you can play with 'A4216113112911594192'
There are many javascript library to support big integer.
BigInteger
This worked for postgres (thanks Bessonov & vitaly-t!)
Just add this before you initialize sequelize
import pg from 'pg'
// Parse bigints and bigint arrays
pg.types.setTypeParser(20, BigInt) // Type Id 20 = BIGINT | BIGSERIAL
const parseBigIntArray = pg.types.getTypeParser(1016) // 1016 = Type Id for arrays of BigInt values
pg.types.setTypeParser(1016, (a) => parseBigIntArray(a).map(BigInt))
A little background:
I didn't want Sequelize to parse bigint columns as strings, so I added pg.defaults.parseInt8 = true. That made pg start parsing bigints as regular numbers, but it truncated numbers that were too big. I ended up going with the above solution.

how to set a value for one property for every record in an array

I have an array with 1 or more records. for every record for ex: there is a property id. I want to set this name to a default value : 8. Please help me.
Array: [{id: 2, name: "x"},{id: 4, name : "y"}]
I tried this way
if (!Ext.isEmpty(detailLineItems) && (detailLineItems.length > 0)) {
canProcess = false;
Ext.Array.forEach(array, function (r) {
if (r.id == 0 || Ext.isEmpty(r.id)) {
canProcess = true;
//how do I set this id
r.id == 6;
}
});
You should not change the internal id of records, as this may break everything; the value in record.id is expected by the framework to be the same value as record.get(record.idProperty). Instead, you should always use the setter method: record.set("id", 8).
But what you are essentially searching for is the defaultValue configuration on your model field:
fields:[{
name: 'id',
type: 'int',
defaultValue: 8
}]
Please be advised that the field id gets a special handling in ExtJS, as long as the model's idProperty defaults to id. A store can contain only one record with the same non-null value in the field defined by idProperty, so if you add them all to the same store you end up with only one of the records, and all other ones are deleted. So if you need multiple records with the same id in the store, you have to change the idProperty on the model to something else, e.g.
idProperty: 'someNonExistentProperty'
This then may cause issues with store sync operations. If you only try to set the id to a fixed value because your backend requires integer id, and the default id generated for new records by ExtJS is non-numeric (e.g. ext-myModel-1), you can check out identifier: 'negative'.
Your question is already answered by Alexander but just to mention, your code statement r.id == 6; is using the equality operator rather than the assignment operator r.id = 6; :-)

Ext.data.field.Date - alternate format

I have to consume an API that provides to me the same field in records in the same array in two possible date formats:
Those where the second is zero will come in Y-m-d H:i format
Those where the second is non-zero will come in Y-m-d H:i:s format
E.g.
[{"date":"2016-12-16 09:52"},{"date":"2016-12-16 09:52:02"}]
An ExtJS store shall consume such API. The field definition:
fields:[{
name:'date',
type:'date',
dateFormat:'Y-m-d H:i:s'
altFormats:'Y-m-d H:i' // <- how can I define this in an `Ext.data.field.Date`?
}]
I know there is a convert function, in which I can write some mess like this:
convert:function(value)
if(Ext.isDate(value)) return value;
var valueWithSecond = Ext.Date.parse(value,"Y-m-d H:i:s");
if(Ext.isDate(valueWithSecond)) return valueWithSecond;
var valueWithoutSecond = Ext.Date.parse(value,"Y-m-d H:i");
if(Ext.isDate(valueWithoutSecond)) return valueWithoutSecond;
}
As can be seen easily, the field definition would be far more readable. Is such a field definition available?
You can extend Ext.data.field.Date and override convert so you'll be able to use it like:
{
name:'date',
type:'my-date',
dateFormat:'Y-m-d H:i:s'
altFormats:'Y-m-d H:i'
}

EXTJS Store issue with Null Values -- useNull: doesn't have an affect --Help?

Folks,
I have a combobox component backed by a JSONStore. The data loaded into the store is returning null for the combobox's value. The value is an int. The JSON decode process is converting the null value into a zero; causing the combobox to fail to render when it attempts to find the pk, zero that doesn't exist in its backing store.
I've found the useNull: config option for data.Field objects, upgraded to 3.3.0 Final and set my int value for the combobox to useNull:true. This isn't having any affect at all, unfortunately. The decoded value is still being changed from null to zero.
Any ideas about how to not set the field to a zero when the data for a JSON field is null?
Here's a pic of what's going on. Notice the data: value is zero, but the JSON value is null.
Thanks!
(gah! stoopid reputation < 10 so I can't directly post the pic. View it here: debug pic )
Also, here's my store's field config:
fields: [
{name:"id", type:"int"},
{name:"occurenceDate", dateFormat: 'Y-m-d\\TH:i:s', type:"date"},
{name:"docketNumber", type:"string"},
{name:"courtLocationId", type:"int", useNull:true},
{name:"assignedOfficerId", type:"int", useNull:true},
{name:"primaryIncidentTypeId", type:"int", useNull:true},
{name:"secondaryIncidentTypeId", type:"int", useNull:true},
{name:"tertiaryIncidentTypeId", type:"int", useNull:true},
{name:"incidentLocation", type:"string"},
{name:"summary", type:"string"},
{name:"personalItemsSeized", type:"string"},
"supplements",
"parties",
"judgeIds"
]
Try using it without type declaration. You may also use convert method:
{
name: "primaryIncidentTypeId",
convert: function(value, row) {
return (value == null) ? null : parseInt(value);
}
}
About the combo width: I usually use
defaults: {
anchor: '100%'
}
in the form declaration and have no problems with widths.
Isnt't it possible to provide convert functions from server side together with all other metadata?
And I'm still using ExtJS 3.2 - no need of any new bugs in the production systems :)
This also got me, you can additionally override the type convert function in Ext.data.Types to allow null values for integer type fields.
Ext.data.Types.INT.convert = function(v){
v = parseInt(String(v).replace(Ext.data.Types.stripRe, ''), 10);
return isNaN(v) ? null : v;
};
You must use defaultValue: null ,useNull : true because default value for integet type is zero
Example:
{name:"primaryIncidentTypeId", type:"int", useNull:true , defaultValue: null },

Resources