Real time data fetching from mysql using Axios in react js - real-time

I am new to react and I'm having some challenges, I want to have real time updating ui using data (complex json object) fetched from a mysql database using axios in react. I was using useEffect to handle the UI rerender however I am having challenges because its causing infinite rerendering, the json data is too complex for the useEffect dependency array. Which approach should I use, will sockets help?
useEffect(() => {
let isMounted = true;
Axios.post('http://localhost:3001/update_irrigation', {
sql: sql
}).then(res => {
if (isMounted) setIrrigator(res.data.results);
})
.catch(err => {
console.log(err);
})
return () => { isMounted = false };
})
here is a sample of the json object array, which is dynamic :
[
{
"ID": 9,
"Sensor_1": 9,
"Sensor_2": 65,
"Sensor_3": 43,
"Sensor_4": 35,
"Sensor_5": 55,
"Sensor_6": 56,
"Sensor_7": 12,
"Sensor_8": 32,
"Sensor_9": 90,
"Sensor_10": 99,
"Solenoid_1": "open",
"Solenoid_2": "open",
"Solenoid_3": "closed",
"Solenoid_4": "closed",
"Solenoid_5": "open",
"Time": "2022-02-17T14:27:49.000Z"
},
{
"ID": 5,
"Sensor_1": 40,
"Sensor_2": 3,
"Sensor_3": 4,
"Sensor_4": 12,
"Sensor_5": 43,
"Sensor_6": 56,
"Sensor_7": 12,
"Sensor_8": 32,
"Sensor_9": 90,
"Sensor_10": 99,
"Solenoid_1": "open",
"Solenoid_2": "open",
"Solenoid_3": "closed",
"Solenoid_4": "closed",
"Solenoid_5": "open",
"Time": "2022-02-17T05:00:00.000Z"
}
]

O you should add an empty array ([]) immediately after the return function that should stop multiple re-rendering
useEffect=()=>{
Do something,
return function {}
, []}

Related

Add json values in to the list of object

How I can get all the values in this JSON and add all the value in to the list of object in the dart?
"data": [
{
"$id": "2",
"serviceId": 1017,
"name": "اکو",
"code": "235",
"price": 1562500,
"isDefault": true,
"transportCostIncluded": false,
"qty": 0,
"minQty": 1,
"maxQty": 2,
"description": "یک دستگاه اکو به همراه دو باند و یک عدد میکروفن (تامین برق بعهده پیمانکار می باشد).",
"contractorSharePercent": 65,
"unitMeasureId": 7,
"unitMeasureName": "هر 60 دقیقه",
"superContractorsId": null
},
],
like this var list = ["2",1017,....]
Assuming you've a JSON file, which you may have parsed like this:
String json = await rootBundle.loadString('file_name.json');
var response = jsonDecode(json);
This is how you can do it:
List<dynamic> jsonData; //similar to var jsonData = [something, something, ...]
//traversing through each value in the key value arrangement of the json
for (var k in response.values) {
jsonData.add(k); //adding each value to the list
}
After the loop ends, jsonData will have all the values of your JSON file.
It's important for you to know that even if you put the keys on a list, they won't necessarily be in order, because of the way maps work.
Assuming your json is a map and not a json string, you could put all of the values on a list like so:
var myList = (jsonObject['data'] as List).fold<List>(
[],
(prev, curr) => [...prev, ...curr.values]
);
if you were talking about a json string:
Map<String, dynamic> jsonObject = jsonDecode(jsonString);
For simplicity, lets assume this json is unparsed in a string.
(1) Assuming the code snippet you added is a string && is valid json you can do as follows :)
import 'dart:convert';
void main() {
var x = json.decode('''
{
"data": [
{
"hello": "2",
"serviceId": 1017,
"name": "اکو",
"code": "235",
"price": 1562500,
"isDefault": true,
"transportCostIncluded": false,
"qty": 0,
"minQty": 1,
"maxQty": 2,
"description": "یک دستگاه اکو به همراه دو باند و یک عدد میکروفن (تامین برق بعهده پیمانکار می باشد).",
"contractorSharePercent": 65,
"unitMeasureId": 7,
"unitMeasureName": "هر 60 دقیقه",
"superContractorsId": null
}
]
}
''');
print(x);
List<dynamic> listOfObjects = (x['data'] as Iterable<dynamic>).toList();
/// this is just gonna be a list of all of your object.
print(listOfObjects);
List<dynamic> listOfValues = (x['data'] as Iterable<dynamic>).map((_object) {
return (_object as Map<String, dynamic>).values.toList();
}).toList();
/// this is gonna be a 2d array here,
print(listOfValues);
}
Hope This helped out:)
Also json here comes from import 'dart:convert';

How to display a single Item from an array of objects - flutter

Hello I need help with a question that's a little tricky. I have an array of objects below. These objects are gotten as a results of a get http request I made to an endpoint. The endpoint requires some Ids and those Ids are also returned in the response objects which are: anchorOid, providerOid, and StateOid. So before this response a user will select an anchor, state and provider then it make request to the end point and return the users Stocks object which is the object below. So whatever the user selects before the http request, those are the IDs that would be returned in the response. So my challenge is after getting the response, before I loop through the whole objects and display them using datatable row and column, how can I display just the anchor, State, before iterating over the whole object just to show the user that this is the anchor and state you selected since the anchor and state are the same in all the objects hence the originate from the users selection. How can can do that please?
_getStocksByProviderIdByAnchorIdBySeasonId() async {
try {
_prefs = await SharedPreferences.getInstance();
var _stockService = StockService();
var result =
await _stockService.getStocksByProviderIdByAnchorIdBySeasonId(
_prefs.getInt('providerOid'),
widget.anchorOid,
widget.seasonOid,
widget.stateOid);
var stocks = await json.decode(result.body);
_stocks = <Stock>[];
stocks.forEach((stock) {
var _stock = Stock();
_stock.oid = stock['oid'];
_stock.date = DateTime.parse(stock['date']);
_stock.anchor = stock['anchor'];
_stock.state = stock['state'];
setState(() {
_stocks.add(_stock);
});
});
print("Stocks");
print(stocks);
setState(() {
data = stocks;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
});
return e.toString();
}
}
I tried to do this:
stocks[0]['anchor]
but its only picking the first index so how do I make the index dynamic I don't know what to do.
[
{
"oid": 3,
"anchor": "MAIZE ASSOCIATION OF NIGERIA",
"anchorOid": 1,
"date": "2021-07-09T14:37:00.403",
"provider": "ERG Agro Solutions",
"providerOid": 1,
"season": "WET SEASON - 2020",
"seasonOid": 1,
"stateOid": 1,
"state": "Abia",
"stockItems": [],
"totalStockItems": 0
},
{
"oid": 4,
"anchor": "MAIZE ASSOCIATION OF NIGERIA",
"anchorOid": 1,
"date": "2021-08-09T14:39:00.403",
"provider": "ERG Agro Solutions",
"providerOid": 1,
"season": "WET SEASON - 2020",
"seasonOid": 1,
"stateOid": 1,
"state": "Abia",
"stockItems": [],
"totalStockItems": 0
}
]
You can try the first method on List like this,
void main() {
List data = [
{
"oid": 3,
"anchor": "MAIZE ASSOCIATION OF NIGERIA",
"anchorOid": 1,
"date": "2021-07-09T14:37:00.403",
"provider": "ERG Agro Solutions",
"providerOid": 1,
"season": "WET SEASON - 2020",
"seasonOid": 1,
"stateOid": 1,
"state": "Abia",
"stockItems": [],
"totalStockItems": 0
},
{
"oid": 4,
"anchor": "MAIZE ASSOCIATION OF NIGERIA",
"anchorOid": 1,
"date": "2021-08-09T14:39:00.403",
"provider": "ERG Agro Solutions",
"providerOid": 1,
"season": "WET SEASON - 2020",
"seasonOid": 1,
"stateOid": 1,
"state": "Abia",
"stockItems": [],
"totalStockItems": 0
}
];
print(data.first['anchor']);
}
It will always pick the first element of an array.

Updating document with mongoose -- one property not being updated?

I have the following code that updates a document in MongoDB:
exercisesRouter.put('/:exerciseId', async (req, res) => {
try {
await mongoose.connect('mongodb+srv://nalanart:password#cluster0.2iplh.mongodb.net/workout-app-db?retryWrites=true&w=majority',
{ useNewUrlParser: true, useUnifiedTopology: true })
await Exercise.findByIdAndUpdate(req.params.exerciseId, {
name: req.body.name,
sessionOne: req.body.sessionOne,
sessionTwo: req.body.sessionTwo,
weight: req.body.weight,
failCount: req.body.failCount,
reps: req.body.reps
})
res.sendStatus(204)
} catch(error) {
throw error
}
})
The problem is that when I use Postman to test it, it updates everything correctly, except the 'reps' property. Here is the JSON body that I put into Postman:
{
"name": "deadlift",
"sessionOne": {
"setsRegular": 4,
"repsRegular": 5,
"setsAmrap": 1,
"repsAmrap": 5
},
"sessionTwo": {
"setsRegular": 0,
"repsRegular": 0,
"setsAmrap": 0,
"repsAmrap": 0
},
"weight": 145,
"failCount": 2,
"reps": [5, 5, 5, 4, 4]
}
This picture shows the document after making the put request (notice reps, which was previously [5, 5, 5, 5, 5] was not updated to [5, 5, 5, 4, 4]
I'm genuinely so confused by this, I feel like it's a small typo in my code that I must have overlooked or possibly something to do with it being an array? Any help is appreciated

How to loop through mongodb subdocument array find the matching elements and update the element fields with new values at once

For example, if a purchase order has line items like this:
and user from the client side send us line items to be updated in an array called lineItemsToUpdate and has a format like this:
[
{ unitCost: 342,
totalQuantity: 13,
acceptedQuantity: 6,
rejectedQuantity: 18,
title: 'Unbranded Concrete Pizza',
description: 'Soft',
variant: 5f2d5eb0195026e6dd549ef0 },
{ unitCost: 189,
totalQuantity: 95,
acceptedQuantity: 49,
rejectedQuantity: 16,
title: 'Handcrafted Rubber Cheese',
description: 'Assurance',
variant: 5f2d5eaf195026e6dd549b7d },
{ unitCost: 267,
totalQuantity: 18,
acceptedQuantity: 93,
rejectedQuantity: 11,
title: 'Incredible Soft Car',
description: 'solution-oriented',
variant: 5f2d5eb0195026e6dd549d3d },
]
here in the lineItemsToUpdate array, it's possible that the value of each element has been changed by the client and I want to update all the matching element by variant field in my sub-document if I describe it in the format of a user story:
update all lineItems "fields" according to lineItemsToUpdate array where the lineItemsToUpdate.[elem].variant === linitem.[elem].variant using $set, if possible $each and arrayFilters operators
I read some example through the mongodb documentation like this one:
db.students2.update(
{ },
{ $set: { "grades.$[elem].mean" : 100 } },
{
multi: true,
arrayFilters: [ { "elem.grade": { $gte: 85 } } ]
}
)
but the problem in here { $set: { "grades.$[elem].mean" : 100 } } is that the 100 value is constant and I want this part dynamic as I described in above.
Following is JS function you have to take help of.
function(c1,arr2){
var arr1 = c1.next().lineItems;
for(i=0;i<arr1.length;i++){
for(j=0;j<arr2.length;j++){
if(arr1[i].variant===arr2[j].variant){
db.purchaseOrder.update(
{ },
{ $set: { "lineItems.$[elem].unitCost" : arr2[j].unitCost,"lineItems.$[elem].totalQuantity" : arr2[j].totalQuantity } .....},
{ multi: true,
arrayFilters: [ { "elem.variant": { $eq: arr2[j].variant } } ]
}
)
}
}
}
}
Explanation
We have to pass 2 parameters: i) Mongo cursor and ii) An array.
Cursor is the collection to be updated. For your case, it is
Purchase Order. Array is lineItemsToUpdate array here.
Next we take 2 for loops to match variant field between cursor and
array.
If there is a match, we update the Purchase Order using update
command and $set operator.
Execution
Go to your Mongo Shell. Ensure the current database has Purchase
Order collection.
Define modifyItems function as below.
var modifyItems=function(c1,arr2){
var arr1 = c1.next().lineItems;
for(i=0;i<arr1.length;i++){
for(j=0;j<arr2.length;j++){
if(arr1[i].variant===arr2[j].variant){
db.purchaseOrder.update(
{ },
{ $set: { "lineItems.$[elem].unitCost" : arr2[j].unitCost,"lineItems.$[elem].totalQuantity" : arr2[j].totalQuantity }... },
{ multi: true,
arrayFilters: [ { "elem.variant": { $eq: arr2[j].variant } } ]
}
)
}
}
}
}
Define a variable arr which contains lineItemsToUpdate.
var arr=[
{ unitCost: 342,
totalQuantity: 13,
acceptedQuantity: 6,
rejectedQuantity: 18,
title: 'Unbranded Concrete Pizza',
description: 'Soft',
variant: 5f2d5eb0195026e6dd549ef0 },
{ unitCost: 189,
totalQuantity: 95,
acceptedQuantity: 49,
rejectedQuantity: 16,
title: 'Handcrafted Rubber Cheese',
description: 'Assurance',
variant: 5f2d5eaf195026e6dd549b7d },
{ unitCost: 267,
totalQuantity: 18,
acceptedQuantity: 93,
rejectedQuantity: 11,
title: 'Incredible Soft Car',
description: 'solution-oriented',
variant: 5f2d5eb0195026e6dd549d3d }
]
Now execute the JS function.
modifyItems(db.purchaseOrder.find({},{"lineItems":1,"_id":0}),arr);
If there is no error, your Purchase Order line items will be now updated with the array values in one single shot.

In Slick Grid inline edit I can't able to get the entire object

I am using angular slickgrid for showing my data. When I am trying to edit the slick grid record, I will get the changed fields only I need the entire object. I have given the sample data.
Columndefinition :
this.columnDefinitions = [
{
id: 'title', name: 'Title', field: 'title', width: 220, cssClass: 'cell-title',
filterable: true, sortable: true,
queryFieldSorter: 'id', type: FieldType.string,
formatter: Formatters.tree,
editor: {
model: Editors.longText,
required: true,
},
},
{ id: 'duration', name: 'Duration', field: 'duration', minWidth: 90, filterable: true },
{
id: 'child.0.percentComplete', name: '% Complete', field: 'child.0.percentComplete', minWidth: 120, maxWidth: 200,
sortable: true, filterable: true, filter: { model: Filters.slider, operator: '>=' },
formatter: Formatters.percentCompleteBar, type: FieldType.number,
editor: {
model: Editors.slider,
minValue: 0,
maxValue: 100,
params: { hideSliderNumber: false },
},
},
];
SlickGrid input data set structure:
const data = [
{
'id': 0,
'indent': 0,
'parentId': null,
'title': 'Task 0',
'duration': '5 days',
'percentComplete': 73,
'start': '2003-03-21T18:30:00.000Z',
'finish': '2003-04-21T18:30:00.000Z',
'effortDriven': true,
'child' : [{
'id': 2,
'indent': 0,
'parentId': 1,
'title': 'Task 0',
'duration': '5 days',
'percentComplete': 73,
'start': '2003-03-21T18:30:00.000Z',
'finish': '2003-04-21T18:30:00.000Z',
'effortDriven': true
}]
},
{
'id': 1,
'indent': 0,
'parentId': null,
'title': 'Task 1',
'duration': '5 days',
'percentComplete': 4,
'start': '2004-04-24T18:30:00.000Z',
'finish': '2004-05-24T18:30:00.000Z',
'effortDriven': false
}
];
When I start to change the employee field oncellchanged called and I got arg.Item
Current behaviour
onCellChanged(e, args) {
this.angularGrid.gridService.updateItemById(args.item['id'], args.item);
console.log(args.item);
}
Log
{
"id": 0,
"indent": 0,
"parentId": null,
"title": "Task 0",
"duration": "5 days",
"percentComplete": 73,
"start": "2003-03-21T18:30:00.000Z",
"finish": "2003-04-21T18:30:00.000Z",
"effortDriven": true,
"child": {
"0": {
"percentComplete": 25
}
}
}
Expected output:
{
"id": 0,
"indent": 0,
"parentId": null,
"title": "Task 0",
"duration": "5 days",
"percentComplete": 73,
"start": "2003-03-21T18:30:00.000Z",
"finish": "2003-04-21T18:30:00.000Z",
"effortDriven": true,
"child": [
{
"id": 2,
"indent": 0,
"parentId": 1,
"title": "Task 0",
"duration": "5 days",
"percentComplete": 25,
"start": "2003-03-21T18:30:00.000Z",
"finish": "2003-04-21T18:30:00.000Z",
"effortDriven": true
}
]
}
Software versions
Angular : 7.3.5
Angular-Slickgrid : 2.17.10
TypeScript : 3.1.6
Node : 10.16.3
The issue due to the utils files used in angular slickgrid library. If you want to fix this issue, have two solutions.
The library itself handle the function logic.
Need to implement custom editor based on your requirement.
Issue area
In each editor, applyValue method sets the object value to respective path. In the method, the array value not parsed properly. You can extend the editor class and override the applyValue method. Here I shared the sample code for your reference. Especially, go through the setDeepValue method which I have mentioned below.
import { EditorArguments, InputEditor } from 'angular-slickgrid';
export class CustomInputEditor extends InputEditor {
constructor(protected readonly args: EditorArguments, inputType: string) {
super(args, inputType);
}
applyValue(item: any, state: any) {
const fieldName = this.columnDef && this.columnDef.field;
if (fieldName !== undefined) {
const isComplexObject = fieldName?.indexOf('.') > 0; // is the field a complex object, "address.streetNumber"
// is the field a complex object having array value you need to specify the index position in path (Here I used 0th index), "address.0.streetNumber"
// validate the value before applying it (if not valid we'll set an empty string)
const validation = this.validate(state);
const newValue = validation?.valid ? state : '';
// set the new value to the item datacontext
if (isComplexObject) {
// when it's a complex object, user could override the object path (where the editable object is located)
// else we use the path provided in the Field Column Definition
const objectPath =
this.columnEditor?.complexObjectPath ?? fieldName ?? '';
this.setDeepValue(item, objectPath, newValue);
} else if (fieldName) {
item[fieldName] = newValue;
}
}
}
setDeepValue<T = any>(obj: T, path: string | string[], value: any) { // Customized the set value method to handle the array data
if (typeof path === 'string') {
path = path.split('.');
}
if (path.length > 1) {
const e = path.shift();
if (obj && e !== undefined) {
let innerObject;
if (!Array.isArray(obj[e]) && typeof obj[e] != 'object') {
obj[e] = {};
}
this.setDeepValue(obj[e], path, value);
}
} else if (obj && path[0]) {
(obj as any)[(path as any)[0]] = value;
}
}
}
I hope this may helpful for you.
Kind information to the library author, If possible update the setDeepValue method in latest release.