JSON object update giving strange result - reactjs
Hi I am updating a json object which has internal array and each object of array has id element. Based on id element I update one of the element which matches the inout id, but it is modifying more than one object. My source code and console logs are given below which will help in understanding the issue.
function
updateUserData(event,id){
var elementName=event.target.name;
console.log('id='+id+', element name='+elementName);
var userData=this.state.user_data;
console.log('User Data before change ='+JSON.stringify(userData));
for(var i=0;i<userData.sports.length;i++){
for(var j=0; j<userData.sports[i].ticket_detail.length;j++){
if(userData.sports[i].ticket_detail[j].id==id){
for(var k=0;k<userData.sports[i].ticket_detail[j].ticket.length;k++){
if(userData.sports[i].ticket_detail[j].ticket[k].paramname==event.target.name){
userData.sports[i].ticket_detail[j].ticket[k].value=event.target.value;
console.log('user data after change ='+JSON.stringify(userData));
this.setState({user_data:userData});
return;
}
}
}
}
}
}
console logs
value=h
id=0, element name=name
User Data before change =
{"total_tickets":3,"total_amount":2124,"htmlid_counter":3,"sports":[{"name":"Badminton","ticket_detail":[{"cat":"Men Singles","formid":102,"ticket":[{"label":"Name:","paramname":"name","type":"text","value":""},{"label":"Email:","paramname":"email","type":"text","value":""},{"label":"Phone:","paramname":"phone","type":"text","value":""}],"id":0},{"cat":"Men
Singles","formid":102,"ticket":[{"label":"Name:","paramname":"name","type":"text","value":""},{"label":"Email:","paramname":"email","type":"text","value":""},{"label":"Phone:","paramname":"phone","type":"text","value":""}],"id":1},{"cat":"Men
Singles","formid":102,"ticket":[{"label":"Name:","paramname":"name","type":"text","value":""},{"label":"Email:","paramname":"email","type":"text","value":""},{"label":"Phone:","paramname":"phone","type":"text","value":""}],"id":2}]},{"name":"Carrom","ticket_detail":[]}],"tournament_id":1}
user data after change =
{"total_tickets":3,"total_amount":2124,"htmlid_counter":3,"sports":[{"name":"Badminton","ticket_detail":[{"cat":"Men Singles","formid":102,"ticket":[{"label":"Name:","paramname":"name","type":"text","value":"h"},{"label":"Email:","paramname":"email","type":"text","value":""},{"label":"Phone:","paramname":"phone","type":"text","value":""}],"id":0},{"cat":"Men
Singles","formid":102,"ticket":[{"label":"Name:","paramname":"name","type":"text","value":"h"},{"label":"Email:","paramname":"email","type":"text","value":""},{"label":"Phone:","paramname":"phone","type":"text","value":""}],"id":1},{"cat":"Men
Singles","formid":102,"ticket":[{"label":"Name:","paramname":"name","type":"text","value":"h"},{"label":"Email:","paramname":"email","type":"text","value":""},{"label":"Phone:","paramname":"phone","type":"text","value":""}],"id":2}]},{"name":"Carrom","ticket_detail":[]}],"tournament_id":1}
You can see from the abobe json , even though input id=0, but json object with id 0 , 1 and 2 are modified. Can someone help me to resolve this issue.
You are doing a asynchronous setState at each iterations. that's probably why you are getting a weird result.
You have to build a new array, then, after your array is what you finally want in your state, you can do:
this.setState({ user_data: newArray })
I found the issue. This issue was happening because each element of array was havinv reference to a common element. That was the reason when I was modifying any one of them, all were been modified.
Related
Why is the array behaving like this
I am working on Angular 6 and i want to post an array of JSON objects using a service class. The following is my function getrerun(data,file){ this.post=[]; for(var i=0;i<data.length;i++) { this.rerun.storeno=data[i].storeNo; this.rerun.filetype=data[i].loadtype; this.rerun.outboundsystem[0]=file; this.rerun.createdate=data[i].createdDate; this.post[i]=this.rerun; console.log("------>"+JSON.stringify(this.rerun)+"------->"+JSON.stringify(this.post)); } this.newurl=this.devurl+"rerun"; return this.http.post<any>(this.newurl,this.post); } newurl is the url of the rest api that i want to hit and this.post is the array that i am sending The value of data is following: [{"lastDate":"2019-02-20 12:36:27","storeNo":"G015","country":"SG","serviceStatus":"FAIL","createdDate":"2019-01-04 11:53:56","loadtype":"F"},{"lastDate":"2019-02-20 10:54:00","storeNo":"G121","country":"SG","serviceStatus":"FAIL","createdDate":"2019-01-23 16:29:33","loadtype":"F"}] and file is 'TP'; However the post array that I am getting is this: [{"outboundsystem":["TP"],"storeno":"G121","filetype":"F","createdate":"2019-01-23 16:29:33"},{"outboundsystem":["TP"],"storeno":"G121","filetype":"F","createdate":"2019-01-23 16:29:33"}] this basically means that both the entries in the array are the same i.e this.post[0].storeno is same as this.post[1].storeno. However, they should have two different values. What do I do about this?
ng2-smart-table display list of object
Is there a way to display a list of objects in a single table cell for ng2-smart-table? I have tried creating a renderComponent but I am getting an empty value. Another question is will the filtering and sorting still work for this?
As I understood , You have a object and you want to display that data in ng2-smart-table. For that follow this step. import { LocalDataSource } from 'ng2-smart-table'; source : any = LocalDataSource; When you call API then you have to set that data in source. this.apiService.POST({}, 'getProductList').subscribe((res) => { console.log(res); this.source = new LocalDataSource(res.data); // Set response as per your res. }); As you can see I have also set one array and that array has objects of data and I have set in table. I hope this may help you. :)
How to check the value of a dropdown?
I am trying to read (using protractor and BDD) the default values of certain dropdowns. To do this, I have tried several lines of code but none of them works. Here is the code that I am using, the console.log is not being executed for some reason. Why? checkDropdownAssignment: function(dropdown,defaultValue) //Function to check the value assigned to a dropdown { let texto=[]; $$('* option:checked').each(function(element, index) { // Execute this operation for each element of the website element.getText().then(function (text) { //Get text of the element in order to compare it with the endpoint afterwards. texto.push(index.toString()); // Add one more component to the vector texto[index]=text; // Save the text in a variable visible outside of this function. console.log(texto[index]); }); }); }, Thanks in advance.
Try this: $$('*option:checked').all(by.tagName('option')).getAttribute('label').then(function(value){ for (var i=0; i<value.length; i++){ expect(value).toContain(arayOfExpectedResults[i]); } }); Here you get an array with all the labels inside the dropdown and compare them with the expected result, or use the array the way you want.
Compare data between two Arrays containing custom Swift Objects
I have some data I have received through an API that return JSON to me. I know I can fetch it and store relevant info from the API into my iOS app. But only while the app is running. I.E. I have not implemented YET how to store the info fetched from the API into UserDefalults. Working on this feature I ran into a problem. I have two Arrays that keeps track of my data. The first Array is the Array I want to store in UserDefaults when I have fetch my data. This one is called "lenders" and keeps LenderData The second Array is my temporary Array. It contains the same type of objects, and this is the one I want to populate with data from the API and then compare to my existing Array "lenders". I want to check if the "lenders" Array contains any object that has the same id as the object I'm looking at in the "lendersTemp" array. If the lenders Array does not contain any LederData object with the id of the tempLender we are currently looking at, we add the tempLender into the lenders Array. How would I go about doing this? My current (non-working) solution is as follows: var lenders = [LenderData]() var lendersTemp = [LenderData]() ... // Get JSON DATA ... for tempLender in self.lendersTemp { if !self.lenders.contains(where: {$0.id == tempLender.id}) { self.lenders.append(tempLender) } } EDIT: My view did load method: var lenders = [LenderData]() var lendersTemp = [LenderData]() override func viewDidLoad() { super.viewDidLoad() downloadJSON { self.myTableView.reloadData() } self.myTableView.rowHeight = 90 myTableView.delegate = self myTableView.dataSource = self }
I figured it out with some help! So this is my answer to my own question! My problem was that getting data from my API is done with an asyc method. And I tried to do comparison after the reload method was called on my TableView. So I did not populate the array the tableview is getting data from, before after the reloadData() had been called and therefore it seemed like my tableview and comparison algorithm, did not work, when in fact it did!
How to map new property values to an array of JSON objects?
I'm reading back record sets in an express server using the node mssql package. Reading back the values outputs an array of Json objects as expected. Now I need to modify the Email propoerty value of each Json object. So I tried looping through the recordset and changing the value at each index: var request = new sql.Request(sql.globalConnection); request.input('p_email', sql.VarChar(50), userEmail); request.execute('GetDDMUserProfile', function(err, recordsets, returnValue) { for (var i = 0; i < recordsets.length; i++){ recordsets[i].Email = "joe#gmail.com"; } console.log(recordsets); }); But instead of modifying the Emailvalue of each Json object, this code just appends a new email property to the last Json object. How can you map new property values to an array of JSON objects? Example output: An example of the output is shown below, where a new Email property has been added to the end of the array instead of changing each existing property value: [ [ { ID:[ 4 ], UserName:"Brian", Email:"joe#gmail.com" }, { ID:[ 5 ], UserName:"Brian", Email:"joe#gmail.com" } Email:'joe#gmail.com' ] ]
The issue here is that your dataset appears to not be an array of JSON objects but, rather, an array of arrays of JSON objects. If you know for certain that you'll always have only one array in the top-most array, then you can solve the problem like this: recordsets[0][i].Email = "joe#gmail.com"; to always target the first array in the top-most array. However, if the top-most array could potentially have more than one array, that'll be a different kind of issue to solve.