remove json attribute where attribute is a variable - javascript

I have a news feed where items in the feed are created from JSON returned from a server. When the user takes an action on an item, I want to remove it from the object via javascript.
The feed looks like this:
{"newsFeed":[{"feedId":"1",
"title":"item1 title",
"desc":"description of the item"},
{"feedId":"2",
"title":"item2 title",
"desc":"description of the item"}]}
I'm trying to remove a JSON attribute or entry where the feedId is passed in via a variable using jQuery. I'm not sure exactly where I'm going wrong here, but when I alert the feed before and after the removal of the object, I'm getting the same response:
function removeFromFeed(feedId){
var newsFeed=jQuery('div#newsFeed').data('newsFeed');
alert(newsFeed.toSource());
delete newsFeed.feedId[feedId]
jQuery('div#newsFeed').data('newsFeed',newsFeed);
alert(newsFeed.toSource());
}

If I undertand you correctly you want to remove e.g. this whole entry {"feedId":"1", "title":"item1 title", "desc":"description of the item"} if removeFromFeed(1) is called.
So what we need to do is remove an entry from an array.
New version which should work now. (btw. what is this toSource() my browser doesn't know this method)
//http://ejohn.org/blog/javascript-array-remove/
Array.prototype.remove = function(from, to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
function removeFromFeed(feedId){
var data = jQuery('div#newsFeed').data('newsFeed');
var len = data.newsFeed.length;
for (var i = 0; i < len; i++) {
if (data.newsFeed[i].feedId == feedId) {
data.newsFeed.remove(i);
break;
}
}
jQuery('div#newsFeed').data('newsFeed', data);
}
Demo: http://jsbin.com/ekali3 (Code view: http://jsbin.com/ekali3/edit)

I'm not sure why the 'Array.prototype.remove' stuff was breaking my page, but I created a new array and just left out the object I wanted to remove.
var newsFeed=jQuery('div#newsFeed').data('newsFeed');
var newFeed={"feed":[]};
alert(newsFeed.toSource());
for (var i = 0; i < newsFeed.length; i++) {
if(newsFeed.feed[f].shiftId!=shiftId){
newFeed.feed.push(newsFeed.feed[f]);
}
}
seems to work.

Related

Look for item value in localstroge

I have a $localstroge with the below stored value:
{"EmployerDetails":{"Distance":30,"EmpLatitude":51.3353899,"EmpLongitude":-0.742856,"EmpNo":39424,"Insitution":null,"PlaceName":"Camberley","TalentPoolLicences":[{"Membership":[{"Identity":39424,"Name":"Weydon Secondary School"}],"TalentPoolType":1},{"Membership":[{"Identity":2,"Name":"North East Hampshire"},{"Identity":4,"Name":"Surrey"},{"Identity":8,"Name":"Surrey"}],"TalentPoolType":3}]},"FacetFilters":{"LastActivity":0,"LocationFilterType":1,"fullorparttime_pex":null,"religion":null,"soughtphase_swk":null,"soughtrole_swk":null,"soughtsubject_swk":null},"LookingFor":null,"OrderBy":null,"PageIndex":1,"PageSize":40}
How can I get the Identity value out from it that sits inside EmployerDetails. I have tried below but it never gets inside if condition:
for (var i = 0; i < localStorage.length; i++) {
if (localStorage.getItem(localStorage.key(i)) === 'EmployerDetails')
{ console.log('hello'); }
}
Any help on this please?
As you're searching for nested key first you need to grab the object and also need to parse it to JSON with JSON.parse then you can proceed as we do in case on normal javascript object
localStorage.getItem('signup-prefs')
This gives me a string containing my object
""name":"google","oauth_version":"2.0","oauth_server":"https://accounts.google.com/o/oauth2/auth","openid":"","username":""}"
After parsing it we can get the object and now we can find the desired property.
JSON.parse(localStorage.getItem('signup-prefs'))
Object {name: "google", oauth_version: "2.0", oauth_server: "https://accounts.google.com/o/oauth2/auth", openid: "", username: ""}
Coming to your problem
Let's say your employee information is like this i am not showing all the fields here.
var empData = {"EmployerDetails":Distance":30,"EmpLatitude":51.33538}}
Then you set the key like this
localstorage.setItem('empData', JSON.stringify(empData))
Now get the string object by key parse it to Json and find the desired key from the object loop over it to get the result.I haven't tested it but i am confident it will work. Let me know if not.
for (var i = 0; i < localStorage.length; i++) {
if (localStorage.key(i) === 'empData') {
// Parse the string to json
var empData = JSON.parse(localStorage.getItem('empData'));
// get all the keys
var keys = Object.keys(empData);
for (var idx = 0; idx < keys.length; idx++) {
// find the desired key here
if (keys[idx] == 'EmployeeDetails') {
var empDetails = empData[keys[idx]]
}
}
}
}
One important thing about your code is
this statement localStorage.key(i)) === 'EmployerDetails' returns either true or false and writing like this
if(localStorage.getItem(localStorage.key(i)) === 'EmployerDetails') will never was executed because you didn't have any key with that name(In practice we should never use keyword as key) .
Did you try to convert it to the json object and then gets the values out?

My update tag function here isn't working

Hi all I am new to angular and would like to know what I am doing wrong in this function.
I am trying to retrieve a firebase child array of tags and compare it with users tags and get an union and post that union back to the firebase array .
Here is my function:
//this retrieved the tag arrays from firebase
$scope.utags = Tag.gettag();
This function converts a firebase array to a JS array .. I initialize it with {{universaltags(utags)}} from the view. Any attempt to initiate the function in the controller using $scope.unversaltags($scope.utags); gives me a blank array
but it works with the views initiation.
$scope.universaltags = function(utag){
var arr1 = [];
for (var i = 0 ; i < utag.length; i++) {
arr1.push(utag[i].$value);
}
return arr1;
};
Also this is the function which I use to find the union and post it back to firebase.
$scope.universaltagupdate = function union_arrays (x,y,Tag) {
var obj = {};
for (var i = x.length-1; i >= 0; -- i) {
obj[x[i]] = x[i];
}
for (var i = y.length-1; i >= 0; -- i) {
obj[y[i]] = y[i];
}
var res = [];
for (var k in obj) {
if (obj.hasOwnProperty(k)) { // <-- optional
res.push(obj[k]);
}
}
//this uses a service to set firebase value
return Tag.updatetag(res);
}
I am not able to initialize both the functions within the controller.
Can you please tell me what is wrong with this approach and what can be the best way to achieve the result? Right now using the functions in curly braces show the results, but how do I accomplish this in the controller?

Strip # from API response with Javascript

I am working with an api that provides a response like this:
{
"statuses": {
"status": [
{
"#array": "true",
"#id": "1",
"#uri": "https://api.com/people/statuses/1",
"name": "Member",
...
]
}
}
I need to use javascript to strip the # out of the key names. Eg "#id" to "id". How can I do this?
You'll have to manually iterate and rename each key and remove the original attribute in a given status. Something like
response.statuses.status.forEach(function(status) {
var keys = Object.keys(status),
keyCount = keys.length;
for (var j = 0; j < keyCount; j++) {
var thisKey = keys[j];
status[thisKey.replace('#', '')] = status[thisKey];
delete status[thisKey];
}
});
Other than looping through the keys and building a new object like everyone else has stated, you could get really crazy and do something like this:
// convert to string, if not already a string response
var responseStr = JSON.stringify(myObj);
// REGEX AWAY THE STUFF
responseStr = reponseStr.replace(/#/g, "");
// convert to obj
myObj = JSON.parse(responseStr);
Although, if any of your data has # in it naturally, it would get regex'ed out. I know, It's crazy. Thought it might be worth mentioning.
You can't just rename the keys within javascript objects, but you could always extend the response object. Something like this would work:
for(var i = 0; i < statuses.status.length; i++){
var status = statuses.status[i];
status.array = status["#array"];
status.id = status["#id"];
status.uri = status["#uri];
// could also delete properties here... see below...
}
That would give you what you were looking for, although all the properties with '#' would still exist. You could take it a step further and delete those properties, though.
delete status["#array"];
delete status["#id"];
delete status["#uri"];
I hope that's what you're looking for. Let me know if that helps!
function stripSymbol(obj) {
var type = Object.prototype.toString.call(obj);
if (type === '[object Array]') {
for (var i = 0, len = obj.length; i < len; i++) {
stripSymbol(obj[i]);
}
} else if (type == '[object Object]') {
Object.keys(obj).forEach(function(key) {
if (key[0] === '#') {
var newKey = key.substr(1);
obj[newKey] = obj[key];
delete key;
key = newKey;
}
stripSymbol(obj[key]);
});
}
}
stripSymbol(data);
This will recursively crawl through and object and remove the '#' at the beginning of any keys.
well first of all array is probably a reserved word for any javascript parser but ignoring that try this...
statuses.status[0].array = statuses.status[0]["#array"];
delete statuses.status[0]["#array"];
the reason you need to do this is because javascript doesn't support renaming keys.

Function is rewriting variable. How is this possible?

This function seems to be rewriting the value for the 'pages' variable and I'm at my wit's end on this one.
I've tried returning the variable through a function, hardcoding the variable into the function, and a pile of other things, but this seems like it should work.
Any ideas?
EDIT:
The output from should be an array of objects formatted like this {default: "Tax Return", safe: "taxreturn"}. The function, when first called with getPages('Both', 'overview', null) and getPages('Both', null, 'overview') does this, but if you call it more times it will error and you will find that the 'pages' variable is now an array of objects.
var pages = [
"Dashboard",
"Overview",
"Contacts",
"Records",
"Cash Flow",
"Transactions",
"Income",
"Expenses",
"Tax Return"
];
var getPages = function(format, includeOne, excludeOne)
{
var pageStrings = pages;
if(includeOne)
for(var p = 0; p < pageStrings.length; p++)
if(uriSafe(pageStrings[p]) == uriSafe(includeOne))
pageStrings = [pageStrings[p]];
if(excludeOne)
for(var c = 0; c < pageStrings.length; c++)
if(uriSafe(pageStrings[c]) == uriSafe(excludeOne))
pageStrings.splice(c, 1);
var outputArray = [];
switch(format)
{
case 'UriSafe':
for(var i = 0; i < pageStrings.length; i++)
pageStrings[i] = uriSafe(pageStrings[i]);
break;
case 'Both':
for(var x = 0; x < pageStrings.length; x++)
{
pageStrings[x] = {
default: pageStrings[x],
safe: uriSafe(pageStrings[x])
};
}
break;
default:
}
function uriSafe(str)
{
return str.replace(' ', '').toLowerCase();
}
console.log(pageStrings);
return pageStrings;
}
var pageStrings = pages;
is creating a reference to the very same array object. When you access it via pageString, you alter the same object which pages does refer to. To create a copy of it (from which you then can splice, assign properties to, etc without altering pages), use
var pageStrings = pages.slice();
I think your confusion is around the following line
var pageStrings = pages;
This does not create a copy of pages it simply creates a reference to pages. This means any edit you make to the value of pageStrings (clearing, changing elements, etc ...) will show up on pages because they refer to the same variable.
If you want pageStrings to have a copy of the pages array then do the following
var pageStrings = pages.slice(0);
var pageStrings = pages; is your hangup. Keep in mind that when you use = in this way, your new var will be a reference if the argument on the right is and array, object, or function. With strings and numbers you will get the copy you were expecting.

Separate Array into two arrays

I wonder how I can separate an array that consists of "123.152323,152.123232" into "123.152323" and "152.123232".
I pick up the string from a rest, the string looks like this.
responseHandler({"items":[{"name":"xxx","location":["xx.xxxxx","xx.xxxxx"]...
function responseHandler(json) {
var markers = new Array();
for (var i = 0; i < json.items.length; i++) {
markers[i] = (json.items[i].location);
}
}
Can I split the location before putting it into an array? I know split() exists but if the string has more information than just location, such as name, city, etc.
Why reinvent the wheel ? It seems like you have a valid json object, Why not simply use JQuery.parseJSON
Modern browser contain native JSON methods (like JSON.parse, JSON.stringify). Use those, or use an external library like this one from google. It makes your life easier (no need for splitting or regex searches and the like):
function responseHandler(json) {
// use native (JSON.parse), json-sans-eval would be: jsonParse(json)
var myJson = JSON.parse(json)
,markers = []
,i = 0
,len = myJson.length;
for (; i < len; i = i+1) {
markers.push(myJson[i].location);
}
return markers;
}
Edit after comment: you are passing a js-object, so JSON-parsing is not necessary.
function responseHandler(json) {
var markers = []
,i = 0
,len = json.length;
for (; i < len; i = i+1) {
markers.push(json.items[i].location);
}
return markers;
}
//for example
var json = {"items":[
{"name":"xxx","location":["xx.xxxxx","xx.xxxxx"]},
{"name":"yyy","location":["yy.yyyyy","yy.yyyyy"]}
]
};
var locations = responseHandler(json);
//=> now locations[0][0] is 'xx.xxxxx', locations[1][0] 'yy.yyyyy'
(May be you should try finding some reading material on the web about javascript basics)

Categories

Resources