How to remove a cookie objects array in $each loop with jquery - javascript

I have a code for cookie object. i want to delete an object which $each loop. How can i do that .
var obj =
{
'deviceid': deviceId,
'full': cookiefull,
'stacked': istoggle
};
var cookieDevObjArray = GetCookieDevObjArray();
if (cookieDevObjArray.length > 0) {
var decoded = $.parseJSON($.cookie("cookieDevObjArray"));
$.each(decoded, function (index, value) {
if (value.deviceid == deviceId) {
//how to delete object from array//
value.deviceId={expire :-1}
}
});
}
$.cookie("cookieDevObjArray", JSON.stringify(obj), { expires: 30 });

Related

Original model is changing when changing the copied data in SAPUI5

I am fetching some data (JSONArray) through an API and saving it in two models and an array variable. I am manipulating data in the array but it is changing the values in the models also. Below are my some code snippets :
onInit : function(){
this.addmodel = new sap.ui.model.json.JSONModel();
this.addmodel.setDefaultBindingMode(sap.ui.model.BindingMode.OneWay);
this.getView().setModel(this.addmodel, "Model");
this.originalModel = new sap.ui.model.json.JSONModel();
this.originalModel.setDefaultBindingMode(sap.ui.model.BindingMode.OneWay);
this.getView().setModel(this.originalModel, "OrgModel");
this.router.attachRoutePatternMatched(this._handleRouteMatched, this);
},
Controller.js :
_handleRouteMatched: function (evt) {
if (evt.getParameter("name") !== "BookMeal") {
return;
}
$.ajax({
url: "/Non_sap_create_requests/odata/MealSelfLocMealType",
method: "GET",
dataType: "json",
success: function (data) {
that.mCopiedArray = $.extend([], data.value);
that.originalModel.setData(data);
that.addmodel.setData(data);
},
error: function (err) {
}
});
onFromDateSelect: function (oEvent) {
if (Date.parse(fromDate) === Date.parse(currentDate)) {
var tempVal = that.mCopiedArray;
tempVal = formatter.mealContsraints(tempVal, currentDate, fromDate, currentTime, "null");
that.addmodel.setProperty("/value", tempVal);
} else {
that.addmodel.setProperty("/value", that.originalModel.getProperty("/value"));
}
},
});
});
In the above code I am saving data in the array mCopiedArray and in 2 models - addmodel and originalModel. I am manipulating the data in formatter.js. Changing the data in mCopiedArray is also changing the data in addmodel and originalModel.
formatter.js :
mealContsraints: function (value, currentDate, fromDate, currentTime, meal) {
if (fromdate === currentdate) {
while (ln--) {
if (value[ln].MealField === "Breakfast") {
value.splice(ln, 1);
break;
}
}
ln = value.length;
if (currentTime > '11:30:00') {
while (ln--) {
if (value[ln].MealField === "Lunch") {
value.splice(ln, 1);
break;
}
}
}
ln = value.length;
if (currentTime > '16:30:00') {
while (ln--) {
if (value[ln].MealField === "Eve Snacks") {
value.splice(ln, 1);
break;
}
}
}
if (currentTime > '18:00:00') {
while (ln--) {
if (value[ln].MealField === "Dinner") {
value.splice(ln, 1);
break;
}
}
}
}
$.extend([], data.value); does not create a deep copy. So if you modify an item in your array (e.g. change MealField from Dinner to Midnight Snack) it will also be changed in the model.
But if you modify the array itself (e.g. remove an item from the array) that should not affect the model.
I did a small snippet for this:
const mData = {value: [
{ MealField: "Dinner", id: 3 },
{ MealField: "Lunch", id: 2 },
{ MealField: "Breakfast", id: 1 }
]};
const oModel = new sap.ui.model.json.JSONModel(mData);
const aCopy = $.extend([], mData.value);
aCopy.splice(1, 1);
// arrays should be different
console.log(aCopy);
console.log(oModel.getProperty("/value"));
aCopy[0].MealField = "Midnight Snack";
// single item should be the same
console.log(aCopy[0]);
console.log(oModel.getProperty("/value/0"));
So the problem shouldn't be the formatter but something else?
Btw your formatter isn't a formatter. A real formatter should return a value and not have side effects (like modifing models/data).
The objects are working reference logic so you can use jquery.extend().
One way to make a deep copy of an object is to serialize it to json and the deserialize it to a new object:
Let objString = JSON.stringfy(obj):
Let newObject = JSON.parse(objString)
PS: that will work for serializable properties and if you have
A huge object you might run into performance issues.

Remove Local Storage JSON Object & Rebuild Array

I'm struggling with the task of removing an item from the LocalStorage...here is my LocalStorage data JSON.
{
"1461569942024" :
{"t_id":1461569942024,"t_build_val":"PreBuild1","t_project_val":"18"},
"1461570048166" :
{"t_id":1461570048166,"t_build_val":"PreBuild2","t_project_val":"17"}
}
here is what I was trying to do:
function removeItem(array, value) {
var idx = array.indexOf(value);
if (idx !== -1) {
array.splice(idx, 1);
}
return array;
}
var newData = removeItem(localStorage['data'], '1461569942024');
I would like to remove na object based on object key eg:1461570048166 and re-save whole array again to the LocalStorage.
Thanks
Try this code
var json = {
"1461569942024": {
"t_id": 1461569942024,
"t_build_val": "PreBuild1",
"t_project_val": "18"
},
"1461570048166": {
"t_id": 1461570048166,
"t_build_val": "PreBuild2",
"t_project_val": "17"
}
};
function deleteItem(input, key) {
delete input[key];
return input
}
localStorage.setItem("localStore", JSON.stringify(json));
localStorage.setItem("localStore", JSON.stringify(deleteItem(JSON.parse(localStorage.getItem("localStore")), '1461570048166')));
JSON.parse(localStorage.getItem("localStore"));

nested for loop in javascript knockout

I have two observable arrays:
var viewModel = {
PositionTypes: ko.observableArray([]),
Users: ko.observableArray([])
}
POSITION ViewModel
var positionViewModel = function (data) {
var _self = this;
_self.PositionName = ko.observable(data.PositionName);
_self.PositionRank = ko.observable(data.PositionRank);
_self.ContentRole = ko.observable(data.ContentRole);
}
positionViewModel.AddPositions = function (data) {
$.each(data, function (index, value) {
positionViewModel.PushPosition(value);
});
};
positionViewModel.PushPosition = function (postion) {
viewModel.PositionTypes.push(new positionViewModel(position));
};
USER ViewModel
// the ViewModel for a single User
var userViewModel = function (data) {
var _self = this;
_self.ID = ko.observable(data.ID);
_self.Name = ko.observable(data.Name);
_self.Email = ko.observable(data.Email);
_self.ContentRole = ko.observable(data.ContentRole);
};
userViewModel.AddUsers = function (data) {
$.each(data, function (index, value) {
userViewModel.PushUser(value);
});
};
userViewModel.PushUser = function (user) {
viewModel.Users.push(new userViewModel(user));
};
How can i using linq.js so that i could loop through every position so i could get all the users for each position?
foreach( each position in positions)
{
foreach(each user in users)
{ list of users for the position}
}
You could also use ko.utils.arrayForEach as follow :
ko.utils.arrayForEach(viewModel.PositionTypes(), function(position){
var usersInPosition = ko.utils.arrayFilter(viewModel.Users(), function(user){
return user.ContentRole() == position.ContentRole();
});
ko.utils.arrayForEach(usersInPosition, function(user){
});
});
See doc
I hope it helps.
Using linq.js, you can perform a join on the columns you want to compare.
Assuming you are joining between the ContentRoles:
var query = Enumerable.From(viewModel.PositionTypes())
.GroupJoin(viewModel.Users(),
"$.ContentRole()", // position selector
"$.ContentRole()", // user selector
"{ Position: $, Users: $$.ToArray() }")
.ToArray();
So I think you want to create an object that contains a mapping of all the positions and user names. You can create such an object using the Aggregate() function to collect all the results into a single object.
var userPositions = Enumerable.From(this.PositionTypes())
.GroupJoin(this.Users(),
"$.ContentRole()", // position selector
"$.ContentRole()", // user selector
"{ Position: $, Users: $$ }") // group all users per position
.Aggregate(
{}, // start with an empty object
function (userPositions, x) {
var positionName = x.Position.PositionName(),
userNames = x.Users.Select("$.Name()").ToArray();
// add the new property
userPositions[positionName] = userNames;
return userPositions;
}
);

chrome.storage.sync.remove array doesn't work

I am making a small Chrome extension. I would like to use chrome.storage but I can't get it to delete multiple items (array) from storage. Single item removal works.
function clearNotes(symbol)
{
var toRemove = "{";
chrome.storage.sync.get(function(Items) {
$.each(Items, function(index, value) {
toRemove += "'" + index + "',";
});
if (toRemove.charAt(toRemove.length - 1) == ",") {
toRemove = toRemove.slice(0,- 1);
}
toRemove = "}";
alert(toRemove);
});
chrome.storage.sync.remove(toRemove, function(Items) {
alert("removed");
chrome.storage.sync.get( function(Items) {
$.each(Items, function(index, value) {
alert(index);
});
});
});
};
Nothing seems to break but the last loop that alerts out what is in the storage still shows all the values I am trying to delete.
When you pass in a string to sync.remove, Chrome will attempt to remove the one single item whose key matches the input string. If you need to remove multiple items, use an array of key values.
Also, you should move your remove call to inside your get callback.
function clearNotes(symbol)
{
// CHANGE: array, not a string
var toRemove = [];
chrome.storage.sync.get( function(Items) {
$.each(Items, function(index, value)
{
// CHANGE: add key to array
toRemove.push(index);
});
alert(toRemove);
// CHANGE: now inside callback
chrome.storage.sync.remove(toRemove, function(Items) {
alert("removed");
chrome.storage.sync.get( function(Items) {
$.each(Items, function(index, value)
{
alert(index);
});
});
});
});
};
Slightly Slimmer and updated solution
chrome.storage.sync.get(null, (data) => {
const keys = Object.keys(data).filter((x) => x.startsWith('<start-of-key>')); // Can replace `startsWith` with regex or any other string comparison
chrome.storage.sync.remove(keys);
});

how to request twitter api without entering a recursion

Anyone knows how can i make requests to twitter api based on text queries without using a recursion.
this is my code
function news_tweets(query, user_id, count) {
news_array = [];
user_tweets = [];
full_array = [];
$.getJSON("https://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=false&user_id=" + user_id +
"&count=" + count + "&callback=?",
function (data) {
$.each(data, function (i, item) {
var user = item.user.name;
var date = item.created_at;
var profile_img = item.user.profile_image_url;
var text = item.text;
var url = (item.entities.urls.length > 0 ? item.entities.urls[0].url : '');
news_array.push({
news_user: user,
news_date: date,
news_profile_img: profile_img,
news_text: text,
news_url: url
});
});
find_tweets(news_array);
});
}
function find_tweets(news_array) {
for (var i in news_array) {
var news_text = news_array[i].news_text;
$.getJSON("http://search.twitter.com/search.json?q=" + news_text +
"&rpp=10&include_entities=true&result_type=mixed&callback=?",
function (data) {
$.each(data.results, function (i, item) {
var user = item.from_user;
var user_id = item.from_user_id;
var date = item.created_at;
var user_profile_img = item.profile_image_url;
var text = item.text;
var url = (item.entities.urls.length > 0 ? item.entities.urls[0].url : '');
user_tweets.push({
user: user,
user_id: user_id,
date: date,
user_profile_img: user_profile_img,
text: text
});
});
combine_arrays(news_array, user_tweets);
});
}
function combine_arrays(news_array, user_tweets) {
full_array = news_array.concat(user_tweets); console.log(full_array);
}
}
when i use console.log("hello") or try to connect the two arrays everything is executed three times.
You seem to have only one instance of the news_array and user_tweets arrays. On those, you push all the result of your api queries. Yet, you call the combine_arrays function on the whole arrays from a loop (each time after the search gave you a new set of results) - running multiple times over some of the items.
I guess re-initializing
var user_tweets = [];
inside the find_tweets function would help something.
You can't access the ajax data outside the callback. Instead, you will need to wait until all the asynchronous requests are resolved. I recommend to use jQuery's Deferred object which makes handling such things much easier:
function news_tweets(query, user_id, count) {
var news_array = [],
user_tweets = [];
return $.getJSON("https://api.twitter.com/1/statuses/user_timeline.json", {
include_entities: "true",
include_rts: "false",
user_i: user_id,
count: count
}).then(function (data) {
return $.when.apply(null, $.map(data, function (item) {
news_array.push({
news_user: item.user.name,
news_date: item.created_at,
news_profile_img: item.user.profile_image_url,
news_text: item.text,
news_url: item.entities.urls.length ? item.entities.urls[0].url : ''
});
return $.getJSON("http://search.twitter.com/search.json", {
q: item.text,
rpp: 10,
include_entities: "true",
result_type: "mixed"
}).done(function (data) {
$.each(data.results, function (i, item) {
user_tweets.push({
user: item.from_user,
user_id: item.from_user_id,
date: item.created_at,
user_profile_img: item.entities.urls.length ? item.entities.urls[0].url : '',
text: item.text
});
});
});
}));
}).then(function() {
// this callback is executed [once] when all requests are done
// and the user_tweets array is filled
// arguments is an array of all search request results
var full_array = news_array.concat(user_tweets);
console.log(full_array);
return full_array;
})
}
Usage:
news_tweets(…).done(function callback(full_array) {
// do something with all the objects
});

Categories

Resources