How to change value of Object inside an Array? - javascript

I want to change the values of the objects inside an array. I have created an object which I insert in every loop in an array.
If encountered with a missing value, I want to update the values of the existing object.
When the loop runs, it always enters the last object details from the api into the array.
Here; the screenshot: https://i.imgur.com/8uqOIaZ.png
var msg = data.message; // messages array from api
let body;
let posts = [];// empty array created
//object structure
let post ={
id:'',
desc: '',
creator: '',
time: '',
likes: 0,
attachment: '',
};
for(let i in msg){
if(msg[i].body.includes(':')){ //if message body include object notation ':'
body = JSON.parse(msg[i].body); // parse text message body into json
if(body.contentDescription){ //if content is true
post.id = body.postId; //id
post.creator = body.createdUserName; //post creator
post.time = body.publishedDate; //post publish date
post.desc = body.contentDescription; //post content
posts.push(post);
}
else if(posts.length > 1){
for(let j in posts){
if(posts[j].id === body.postId){
console.log(posts[j].id);
if(body.likeCount){ //if likeCount is true
posts[j].likes += 1; //increase like count
}else if(body.attachmentId){ //of Attachment is true
posts[j].attachment = body.attachmentId; // update attachement value
}
}
break;
}
}
}
};
Please help where am I doing it wrong?

Objects in JavaScript are sent via a link to the piece of memory. So when you change your post you are changing all the posts because all of them are looking to the same piece of memory.
You can change your code in a next way so it start working correct
...
if(body.contentDescription){ //if content is true
let postItem = Object.assign({}, post); // Coping an object so breaking the memory link
postItem.id = body.postId; //id
postItem.creator = body.createdUserName; //post creator
postItem.time = body.publishedDate; //post publish date
postItem.desc = body.contentDescription; //post content
posts.push(postItem);
}
...
However, there is more than one way to skin a cat so this is not the only solution.

Related

Parsing strings from local storage with vanilla JavaScript [duplicate]

This is my code. I am trying since a couple of days to create an Array of Objects, which I will then store in Local Storage. Here is the problem, I need to first Get the existing value from Local Storage.
I then need to add the new data object to the existing array. I then convert it into JSON so that I can store it back in the local storage.
onRegisterSubmit(){
const user = {
a: this.a,
b: this.b,
c: this.c,
id: Date.now()
}
var abc = [];
var get = JSON.parse(localStorage.getItem('user'));
abc = [get];
abc.push(user);
localStorage.setItem('user', JSON.stringify(abc));
console.log(JSON.stringify(abc));
console.log(get);
}
I want the JSON to be an array of objects like this,
[{"hour":1,"minute":21,"ampm":"PM","repeatDays":[],"message":"","todayOrTomorrow":"Tomorrow","isRepeatMode":false,"isEnabled":false,"id":"1493797882440"},{"hour":1,"minute":24,"ampm":"PM","repeatDays":[],"message":"","todayOrTomorrow":"Tomorrow","isRepeatMode":false,"isEnabled":false,"id":"1493797896257"},{"hour":6,"minute":14,"ampm":"PM","repeatDays":[],"message":"","todayOrTomorrow":"Tomorrow","isRepeatMode":false,"isEnabled":false,"id":"1493815470408"}]
This is my JSON.
[[[[[[[{"id":1493820594019},{"id":1493820606448}],{"id":1493820609111}],{"id":1493820610150}],{"id":1493820610553}],{"id":1493820610827}],{"id":1493820611015}],{"id":1493820612018}]
I've been trying for several days and any help will be greatly appreciated.
The issues with that code are:
You're wrapping the result you get in an array, but in theory, you want to already have an array.
You're storing user, not get or abc. (You removed that with an edit.)
To store the array, do what you're doing:
localStorage.setItem("users", JSON.stringify(users));
To get the array:
users = JSON.parse(localStorage.getItem("users") || "[]");
Note how that provides a default (empty array) if getItem returns null because we've never stored our users there.
To add a user to the array:
users.push({id: 1, foo: "bar"});
Example (live on jsFiddle [Stack Snippets don't allow local storage]):
(function() { // Scoping function to avoid creating globals
// Loading
var users = JSON.parse(localStorage.getItem("users") || "[]");
console.log("# of users: " + users.length);
users.forEach(function(user, index) {
console.log("[" + index + "]: " + user.id);
});
// Modifying
var user = {
id: Math.floor(Math.random() * 1000000)
};
users.push(user);
console.log("Added user #" + user.id);
// Saving
localStorage.setItem("users", JSON.stringify(users));
})();
That shows you the list of current users in the console, adding one each time you refresh the page.
Try something like this:-
link https://jsfiddle.net/sureshraina/nLexkyfw/1/
var mydatas = new Array();
mydatas[0] = "data";
mydatas[1] = "data1";
mydatas[2] = "data2";
localStorage["mydatas"] = JSON.stringify(mydatas);
var datas = JSON.parse(localStorage["mydatas"]);
See this post.
You can't store Objects, you have to store a String. So the workaround is to stringify your Object before you store it (for example, you could use change it to a JSON object, store it, and read it again when needed).

How to traverse back through the tree after reaching to the end in DFS- Javascript

This may sound very naive, but I'm working my path through algos and need help in figuring out the traversal using DFS.
I'm getting the response from a fetch () and storing the data in an array. and using Array.shift() to get the first node from the array, pass it to the url as an id and call for another fetch() to get data related to that id.
By doing this I do reach the end of one side, however I dont know how should I go back to the root and check if there are any more children.
here is code:
data={
id: "647634",
depth: 1,
data: ["node1","node2","node3"]
}
the data for every node call look like above.
function getData(id, explored) {
var self = this;
let explored = visited && visited.length>0 ? visited : new Array();
fetch("https://test.com/id", function(data){
//here im checking if its the end child:
if (data.end) {
var end =[];
end.push(data.end); // o/p: endId: "7287382"
}else {
let s = new Array();
data.forEach(function(n){
s.push(n);
})
var t = s.shift();
explored.push(t);
self.getData(t,explored)
}
});
}
any ideas?

JS, issue with keeping array data in sessionStorage

Here is the problematic code:
let newFriend = event.target.id;
let friends;
if (sessionStorage.getItem('friends') === null || sessionStorage.getItem('friends') === undefined || sessionStorage.getItem('friends') === '') {
console.log('DEV_NO FRIENDS!sessionStorage[\'friends\']: ' + sessionStorage.getItem('friends'));
friends = [newFriend];
} else {
let currentFriends = sessionStorage.getItem('friends').split(',');
console.log(currentFriends.length);
// let currentFriends = JSON.parse(sessionStorage.getItem('friends'));
console.log('DEV_sessionStorage friends: ' + currentFriends);
console.log('DEV_inArray condition: ' + $.inArray(newFriend, currentFriends));
if (!($.inArray(newFriend, currentFriends) !== -1)) {
console.log('DEV_if not in array!');
friends = currentFriends.push(newFriend);
console.log('DEV_friends in if: ' + friends);
}
}
let data = {friends: friends};
It is hooked on image tag. The sessionStorage fills on successful login like so:
if (response['friends'] !== undefined) {
sessionStorage.setItem('friends', response['friends']);
} else {
sessionStorage.removeItem('friends');
}
Or is updated like so, if new friend is added:
ajax(url, 'GET', 'none', 'Kinvey', function(response) {
sessionStorage.setItem('friends', response['friends']);
});
The idea is: a user can add friends to his friends list. The friend is 'PUT' into my app's back-end, inside a column called 'friends'. Then sessionStorage is updated to store the new friend. To my knowledge sessionStorage supports only strings, so I thought lets store the friends as string, separated by ",". Then I would pick that up ('currentFriends') and split that string into array. Then push the next item and send the data back to the server, then update sessionStorage. But I simply cannot do it - I've been trying for over 3 hours now. As you can see with the numerous console.log()s, for some reason I cannot process my data accordingly and I have no idea what am I doing wrong. Sorry for the long post, but I'm really stuck in here..
Bottom line: as #dfasoro kindly explained - when working with REST one should always make sure he keeps his data in JSON strings. My second problem was that array.push() returns integer (length of array) instead of new array.
I hope this will help you, I have helped you refactor your code and removed unneccesaries, I hope the inline comments help you as well.
IMAGE HOOK CODE
let newFriend = event.target.id;
let friends = [];
if (sessionStorage.getItem('friends')) {
try {
//this will throw an error if invalid array json is in friends sessionStorage
friends = JSON.parse(sessionStorage.getItem('friends'));
}
catch (e) { }
}
//is friend in the array?
//if not add and store back into sessionStorage
if (friends.indexOf(newFriend) == -1) {
friends.push(newFriend);
sessionStorage.setItem('friends', JSON.stringify(friends));
}
let data = {friends: friends};
//continue with your image hook code
LOGIN CODE
//login code
if (response['friends']) {
sessionStorage.setItem('friends', JSON.stringify(response['friends']));
} else {
sessionStorage.removeItem('friends');
}
PUT CODE
//update PUT code
ajax(url, 'GET', 'none', 'Kinvey', function(response) {
sessionStorage.setItem('friends', JSON.stringify(response['friends']));
});
You basically store the data as JSON string and retrieve as JSON object. You also don't need the null, undefined, empty test etc. You are basically trying to test for a falsy value.
I also really hope that your response object is a standard JSON object mapped to a friend array and not a comma separated list of friends e.g.
{"friends": [4, 5, 3, 2]} and not `{"friends": "4, 5, 3, 2"}"
The above works perfect as sessionStorage only uses a key value pair.
Though I also use sessionJS to get/set/delete data to/from sessionStorage
maybe this will also help you.

AngularJS - grabbing specific data from an JSON array

Here is a picture of what the API is returning:
I am trying to create variables that grab the "Current Approver" and "Status" from this array. And if the "Current Approver" matches the username stored in local storage and the "Status" is "REJECTED" then I want to run a line of jquery.
Here is what I have:
$http.get( API + '/car' ).
success(function(data) {
$scope.myCars = data;
console.log(data);
var originator = $scope.myCars["My CARs"]["Current Approver"],
status = $scope.myCars["My CARs"].Status,
user = localStorage.getItem('user') || null
// Check if logged in user is originator and CAR is "REJECTED"
if (originator === user && status === 'REJECTED') {
$('#termCar').css('display', 'block');
}
});
Here is the HTML:
<div ng-repeat="car in myCars['My CARs']" class="myCar">
<div class="carId">{{ car['Display Name'] }}</div>
<div class="title">{{ car['Project Title'] }}</div>
<div id="termCar" class="termCar"><a ui-sref="taskDetails">Terminate</a></div>
</div>
I know that it has something to do with these lines (obviously):
originator = $scope.myCars["My CARs"]["Current Approver"],
status = $scope.myCars["My CARs"].Status
I just cant figure out how to pull specific data out of an array i guess.
I need to be able to loop through the array of objects and find the ones that meet that if statement and then if one of those does then run the jQuery line.
Thanks for any help.
Try:
originator = $scope.myCars["My CARs"][0]["Current Approver"];
status = $scope.myCars["My CARs"][0].Status
You're simply not referencing which index in the array you wish to grab the values from.
You're right, the issue is this:
$scope.myCars["My CARs"]["Current Approver"]
For that to work, your data structure would have to look like this:
"My CARS": {
"Current Approver": "..."
}
My CARs is an array of objects, so you need to iterate over that array. You would typically do this with a basic forEach. Lodash makes this nice to do, but I'll use native js:
var user = localStorage.getItem('user');
$http.get('/car').success(function(data) {
var cars = data['My CARs'];
cars.forEach(function(car) {
if (car["Current Approver"] === user && car.Status === 'REJECTED') {
// do stuff
}
});
});
you need to filter the array My CARs to match the local user
$http.get(API + '/car').success(function(data) {
$scope.myCars = data;
console.log(data);
var user = localStorage.getItem('user') || null;
var originator = $scope.myCars["My CARs"].filter(function(d) {
return d["Current Approver"] === user && d["Status"] === 'REJECTED'
});
if (originator.length) {
$('#termCar').css('display', 'block');
}
});
Try this:
var cars = $scope.myCars["My CARs"];
for(int i = 0; i < cars.length; i++) {
var theCar = cars[i];
if(theCar["Current Approver"] === user && theCar["Status"] === "REJECTED") {
originator = theCar["Current Approver"];
status = theCar.Status;
break;
}
}
This will give you the status of the first car that matches whose Current Approver matches the user.

Parsing JS array with JS and then passing it to PHP

I'm making a system for calculating road taxes in the netherlands, there for i got a few JS arrays (where the data is in) which i'm parsing with JS (all at the same time, because it's the same format of data), then passing it to PHP as JSON format using the XMLHttpRequest object.
For this i first made this data mapper:
var roadTaxData = {
provinceWeightFuelPricesData: {
personen_auto: {
noord_holland: dataNoordHolland,
zeeland: dataZeeland
//TODO: Add all the provinces with it's data to the personen_auto object
},
kampeer_auto: {
noord_holland: dataNoordHolland2,
zeeland: dataZeeland2
}
}
}
The format of this is:
Vehicle type
Which province
The data belonged to that province.
I've then made this small parser to parse it to an array:
/*
Loop through all the specific vehicle types inside the provinceWeightFuelPricesData object
*/
for (var vehicleType in roadTaxData.provinceWeightFuelPricesData) {
/*
Where the data is getting stored for each vehicle type
*/
var data = {},
/*
Every province with its data contained in the vehicle type
*/
provinces = roadTaxData.provinceWeightFuelPricesData[vehicleType];
/*
Loop through all province's with its data in the specific vehicle type
*/
for (var province in provinces) {
/*
Define each province data
*/
var provinceData = provinces[province];
/*
Add the province to the object as an key
*/
data[province] = [];
/*
Loop through the data which belongs to every province
*/
for (var provinceDataIndex = 0; provinceDataIndex < provinceData.length; provinceDataIndex++) {
/*
Add the province data to the array
*/
data[province].push(provinceData[provinceDataIndex]);
}
console.log('Parsed a the province: ' + province + " from the vehicle type " + vehicleType);
console.log('');
}
console.log('Parsed the vehicle type: ' + vehicleType);
console.log('');
console.log(data);
passToPHP(vehicleType, JSON.stringify(data));
}
This is all going great, and gives me back the correct array with data when i do this:
console.log(data);
But when i've passed it to PHP with this method:
function passToPHP (paramName, data) {
if (typeof paramName === "string" && typeof data === "string") {
var httpc = new XMLHttpRequest(); // simplified for clarity"
httpc.open("POST", INSTALL_FILE, true); // sending as POST
httpc.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
/*
For testing
*/
httpc.onreadystatechange = function () { //Call a function when the state changes.
if (httpc.readyState == 4 && httpc.status == 200) { // complete and no errors
console.log(httpc.responseText); // some processing here, or whatever you want to do with the response
}
};
httpc.send(paramName + "=" + data);
}
}
With this PHP file:
header('Content-Type: application/json');
$personen_auto = $_POST['personen_auto'];
$kampeer_auto = $_POST['kampeer_auto'];
print_r(json_decode($personen_auto));
print_r(json_decode($kampeer_auto));
I get this error first, which doesn't reconize the kampeer_auto index from $_POST, which i actually send:
Notice: Undefined index: kampeer_auto in
C:\Users\Bas\Documents..\Cars\install.php on line 6
Then the data log of the personen_auto object.
Then another error with this message, which does't reconize the personen_auto index, which i also just parsed and printed out?
Notice: Undefined index: personen_auto in
C:\Users\Bas\Documents..\Cars\install.php on line 5
Questions
How does this come that it doesn't reconize those $_POST variables?
How will i be able to make PHP receive more then only 1 $_POST index at the time?
My own try
I've tried putting the passPHP() method outside of the for loop, like this:
/*
Loop through all the specific vehicle types inside the provinceWeightFuelPricesData object
*/
for (var vehicleType in roadTaxData.provinceWeightFuelPricesData) {
/*
Where the data is getting stored for each vehicle type
*/
var data = {},
/*
Every province with its data contained in the vehicle type
*/
provinces = roadTaxData.provinceWeightFuelPricesData[vehicleType];
/*
Loop through all province's with its data in the specific vehicle type
*/
for (var province in provinces) {
/*
Define each province data
*/
var provinceData = provinces[province];
/*
Add the province to the object as an key
*/
data[province] = [];
/*
Loop through the data which belongs to every province
*/
for (var provinceDataIndex = 0; provinceDataIndex < provinceData.length; provinceDataIndex++) {
/*
Add the province data to the array
*/
data[province].push(provinceData[provinceDataIndex]);
}
console.log('Parsed the province: ' + province + " from the vehicle type " + vehicleType);
console.log('');
}
console.log('Parsed the vehicle type: ' + vehicleType);
console.log('');
//console.log(data);
}
passToPHP(vehicleType, JSON.stringify(data));
But that passed only one variable to PHP (which was kampeer_auto).
the code is sending only one vehicleType per call to php. The relevant code is
for (var vehicleType in roadTaxData.provinceWeightFuelPricesData) {
data = ...
passToPHP(vehicleType, JSON.stringify(data));
}
The first call passes 'personen_auto' only (and kampeer_auto is undefined); the second call passes only 'kampeer_auto' and personen_auto is undefined.
The revised version of the code that moves passToPHP outside the loop still resets data each time through the loop, so at the bottom data will contain only the very last auto's provinces.
To pass all autos, data needs to be appended to (not re-initialized), data has to be gathered into auto-specific sections (not intermingled), and passToPHP needs to build a multi-parameter query string, one per auto. All that will pretty much rebuild the roadTaxData object.
Or just pass all of roadTaxData.provinceWeightFuelPricesData to php and have php loop and separate the auto types.
Edit: you don't need to convert objects to arrays when passing them to php. Php's json_decode() can decode objects into associative arrays when the optional second parameter is set to true, as json_decode($data, true). Simply
passToPHP('json', JSON.stringify(roadTaxData.provinceWeightFuelPricesData));
and in php
$data = json_decode($_POST['json'], true);
$kampeer_auto = $data['kampeer_auto']);
$personen_auto = $data['personen_auto']);
try passing the data to php as an un-parsed json string, and parse it explicitly with json_decode.
So send a single $_POST parameter json=string (string is the urlencoded JSON.stringify of the data), and have php decode json_decode($_POST['json'], true). That should return an array that represents the js object.
Try putting declaration for data outside the loop. It's currently getting reset/cleared for each entry in roadTaxData.provinceWeightFuelPricesData so you will only ever send the last entry to the server.
var data = {};
for (var vehicleType in roadTaxData.provinceWeightFuelPricesData) {
Then, as #Andras suggested, you need to decode the JSON on the server side:
$data = json_decode( $_POST['json'], true );
$personen_auto = $data['personen_auto'];
$kampeer_auto = $data['kampeer_auto'];

Categories