How to Store Local Arrays Properly from subsequent requests in AngularJS - javascript

I want to have a local array that stores "last messages" (inbox view). In my service i do a GET request that returns a data structure like this:
[{id:1, from_user:1, to_user:2, message:"bar", has_been_read:false},
{id:2, from_user:3, to_user:2, message:"foo", has_been_read:false}]
The server only sends last messages with has_been_read == false, this is the code for the service:
$scope.unreadMessages = []
$scope.GetUnreadMessages = function(){
$localStorage.AllMessages.push($scope.unreadMessages)
UserService.GetUnreadMessages()
.success(function (data) {
data = angular.fromJson(data);
$scope.unreadMessages.push(data);
}).
error(function(error) {
//do something
});
}
$scope.GetUnreadMessages()
Let's say In my given example json above I read id:1 which cause the, has_been_read to become true.. on the next request it will only return the data id:2, which is correct.. but my problem is the new request data replaces ALL my old data. so what i want to happen is, even if i read id:1 unless i deleted it or i have a new message from the same user, I still want to keep it when i make new requests.. I know my code is wrong just don't know how to go about this..

One possible solution is to save the responses grouped by from_user:
.success(function(unreadMessages){
angular.forEach(unreadMessages, function(unreadMessage){
// if conversation from a user exists
if(localStorage.getItem(unreadMessage.from_user)){
var conversation = JSON.parse(localStorage.getItem(unreadMessage.from_user));
conversation.push(unreadMessage);
localStorage.setItem(unreadMessage.from_user, JSON.stringify(conversation));
} else {
var conversation = [];
conversation.push(unreadMessage);
localStorage.setItem(unreadMessage.from_user, JSON.stringify(conversation));
}
});
})

Related

Angular 2 Observables - Empty response on action still shows data in array

I have this function that aggregates some user data from Firebase in order to build a "friend request" view. On page load, the correct number of requests show up. When I click an "Accept" button, the correct connection request gets updated which then signals to run this function again, since the user is subscribed to it. The only problem is that once all of the friend requests are accepted, the last remaining user stays in the list and won't go away, even though they have already been accepted.
Here is the function I'm using to get the requests:
getConnectionRequests(userId) {
return this._af.database
.object(`/social/user_connection_requests/${userId}`)
// Switch to the joined observable
.switchMap((connections) => {
// Delete the properties that will throw errors when requesting
// the convo keys
delete connections['$key'];
delete connections['$exists'];
// Get an array of keys from the object returned from Firebase
let connectionKeys = Object.keys(connections);
// Iterate through the connection keys and remove
// any that have already been accepted
connectionKeys = connectionKeys.filter(connectionKey => {
if(!connections[connectionKey].accepted) {
return connectionKey;
}
})
return Observable.combineLatest(
connectionKeys.map((connectionKey => {
return this._af.database.object(`/social/users/${connectionKey}`)
}))
);
});
}
And here is the relevant code in my Angular 2 view (using Ionic 2):
ionViewDidLoad() {
// Get current user (via local storage) and get their pending requests
this.storage.get('user').then(user => {
this._connections.getConnectionRequests(user.id).subscribe(requests => {
this.requests = requests;
})
})
}
I feel I'm doing something wrong with my observable and that's why this issue is happening. Can anyone shed some light on this perhaps? Thanks in advance!
I think you nailed it in your comment. If connectionKeys is an empty array calling Observable.combineLatest is not appropriate:
import 'rxjs/add/observable/of';
if (connectionKeys.length === 0) {
return Observable.of([]);
}
return connectionKeyObservable.combineLatest(
connectionKeys.map(connectionKey =>
this._af.database.object(`/social/users/${connectionKey}`)
)
);

Firebase not saving data?

I'm trying to scrape a webpage, and save the data to Firebase. I can console.log the data, but I can't get it to save. At first I thought the tabletojson function took a second to grab the data, so I decided to put the Firebase part where I save data into a separate function.
When I run this in the terminal, the console.log doesn't appear because something is going wrong with saving the data to Firebase. Any ideas on how to fix this script?
var tabletojson = require('tabletojson');
var Firebase = require('firebase')
var url = 'https://en.wikipedia.org/wiki/List_of_sovereign_states#List_of_states';
tabletojson.convertUrl(url, function(tablesAsJson) {
var listofSovereignStates = tablesAsJson[0];
sendToFirebase(listofSovereignStates)
});
function sendToFirebase(data) {
dataRef = new Firebase("https://mikesweather.firebaseio.com/flags")
dataRef.set(data)
console.log(data)
}
Try this:
function sendToFirebase(data) {
var dataRef = new Firebase("https://mikesweather.firebaseio.com/flags")
dataRef.set({myData: data})
console.log(data)
}
Per the example below you can see that you need to pass in an object to set:
dataRef.set({
alanisawesome: {
date_of_birth: "June 23, 1912",
full_name: "Alan Turing"
}
});
https://www.firebase.com/docs/web/guide/saving-data.html
Edit, after thinking about it, it is possible this is not the solution, let me know if this works...

Ember data model arrays don't always have data

First time building an Ember app and I'm having difficulty with my models not resolving.
I have a set of Course models, each of which has an array of User models (hasMany, with async: true).
When I load the page, I see all of the API requests are correct (i.e. the client is making requests for all of the users in the array), and when I log the course model (i.e. when I do console.log(course)), I see the data in the console. However, when I do something like course.get('admins'), the array is empty.
The Course is not the model of the controller that needs all of this information (could this be why this is happening?), so I put the 'course' controller in the needs array.
In the end it's something like this:
var course = this.get('controllers.course').get('model'); // this is OK, has data
var admins = course.get('admins'); // this is not OK, has no data!
Even when I try something like:
course.get('admins').then(function (admins) {
console.log(admins);
});
There's still no data! What am I doing wrong?
Here's more of the relevant code:
var VideoDiscussionController = Ember.Controller.extend({
needs: ['course'],
submitComment: function () {
var user = this.get('session').get('currentUser'),
admins = this.get('controllers.course').get('model').get('admins'), // this is empty!
isAdmin = admins.isAny('id', user.get('id'));
var video = this.get('model'),
text = this.get('commentText'),
seconds = this.player.getCurrentTime() : 0,
comment = this.store.createRecord('comment', {
video: video,
text: text,
seconds: seconds,
author: user,
isAdmin: isAdmin
});
// POST comment
comment.save();
// Clear textbox
this.set('commentText', '');
video.get('comments').pushObject(comment);
}
});
I assume your model is something like this:
var CourseModel = DS.Model.extend({
admins: DS.hasMany('user', {
async: true
})
});
then, if you get your course model instance and if you do:
course.get('admins')
that line should trigger the AJAX call asking for the users.
Have you checked if such a request is called?
If not, could you provide some more code so that we can help you?

Parse.com master key doesn't let to write PFUser currentUser

UPDATE: In a nutshell, I would like to use the Master key, because I need to write an other user object with my current user, but I don't want to override all security, I just wanna use it in one function. The accepted answer in this question gave a very nice starting point, however I couldn't make it to work. It's the last code block in this question.
I have two separated functions. The first is pure objective-c, it deletes users from the currentUser's firstRelation. It worked well without any problems until i added a different CloudCode function into a different view controller. The CloudCode function uses the master key and adds currentUser to otherUser's sampleRelation & adds otherUser to currentUser's sampleRelation (firstRelation and sampleRelation is two different column inside the User class).
So the problem is when I delete a user from currentUser's firstRelation (with current user) my app crashes, because the user must be authenticated via logIn or signUp. Actually i don't understand this, because in this case I'm writing the currentUser with the currentUser instead of another user, so it must work without any problems (and worked before the CloudCode).
I'm almost sure that it's because I'm using the master key with the CloudCode, but have no idea how can I avoid it. Everything else is still working, for example I can upload images with currentUser.
Here is the code that I'm using for the CloudCode, JavaScript is totally unknown for me, maybe somebody will see what causes the problem.
Parse.Cloud.define('editUser', function(request, response) {
Parse.Cloud.useMasterKey();
var userQuery = new Parse.Query(Parse.User);
userQuery.get(request.params.userId)
.then(function (user) {
var relation = user.relation("sampleRelation");
relation.add(request.user);
// chain the promise
return user.save();
}).then(function (user) {
var currentUser = request.user;
var relation = currentUser.relation("sampleRelation");
relation.add(user);
// chain the new promise
return currentUser.save();
}).then(function () {
response.success();
}, function (error) {
response.error(error);
});
});
It crashes when i try to remove the object:
PFUser *user = [self.friends objectAtIndex:indexPath.row];
PFRelation *myFriendsRel = [self.currentUser relationForKey:#"simpleRelation"];
if ([self isFriend:user]) {
for (PFUser *friendName in self.friends) {
if ([friendName.objectId isEqualToString:user.objectId]){
[self.friends removeObject:friendName];
break; // to exit a loop
}
}
// remove from parse
[myFriendsRel removeObject:user];
NSLog(#"deleted: %#", user.username);
}
[self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error){
NSLog(#"Error %# %#", error, [error userInfo]);
}
}];
This is the newest attempt, that based Fosco's answer from the other question. It works, but the same way as the earlier versions.
Parse.Cloud.define('editUser', function(request, response) {
var userId = request.params.userId;
var User = Parse.Object.extend('_User'),
user = new User({ objectId: userId });
var currentUser = request.user;
var relation = user.relation("friendsRelation");
relation.add(currentUser);
user.save(null, { useMasterKey:true}).then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
At a quick glance it looks like its failing because you're trying to remove an object from an array whilst it is being iterated. I know this causes a crash in Objective C regardless of whether you're using Parse objects or not.
Try re-writing this segment:
for (PFUser *friendName in self.friends) {
if ([friendName.objectId isEqualToString:user.objectId]){
[self.friends removeObject:friendName];
break; // to exit a loop
}
}
To something like this:
NSMutableArray *tempArray = [[NSMutableArray alloc]init];
for (PFUser *friendName in self.friends) {
if (![friendName.objectId isEqualToString:user.objectId]) {
[tempArray addObject:friendName];
}
self.friends = [NSArray arrayWithArray:tempArray];
Again, only had a quick glance so not 100% if that is your problem but it looks like it, let me know if it helps

Cant get the current id of a data from local Storage using jquery

I am working on an app to store data offline. My problem is when I try to retrieve the data from local storage for update/edit, it keeps calling only the id of the first item, and not calling the id of the data in view.
Please what am I doing wrong?
Here is my code for loading employees:
// load cases from localStorage
var employees;
if (localStorage.getItem('employees')) {
employees = JSON.parse(localStorage.getItem('employees'));
} else {
// If no cases, create and save them
employees = [];
// offling storing of our cases
localStorage.setItem('employees', JSON.stringify(employees));
}
// show case listing in list view page
var showEmployees = function () {
//erase existing content
$('#employee_list').html('');
//insert each employee
for (var i = 0; i<employees.length; i++) {
addEmployees(employees[i]);
}
};
Here is my code to add an employee to list view:
//add an eliment to list view
var addEmployees = function (empData) {
//HTML content of one list element
var listElementHTML = '<li><a class="employee_list" ui-btn ui-btn-e ui-btn-icon-right ui-icon-carat-r" data-transition="fade" data-split-icon="delete" href="#item'+empData.id+'">' + empData.employeename + '<br> ' + empData.dateofbirth + '</br></a></li>';
//appending the HTML code to list view
$('#employee_list').append(listElementHTML);
};
Here is my code for Edit function:
//User input to edit form
$('#edit_employee_page').on('click' , function () {
var editEmployee = JSON.stringify({
id: employees.length+1,
employeeno: $('#employeeno').val(),
employeename:$('#employeename').val(),
stateoforigine:$('#stateoforigine').val(),
employeephone: $('#employeephone').val(),
dateofbirth:$('#dateofbirth').val()
});
//Alter the slected data
localStorage.setItem("employees", JSON.stringify(employees));
return true;
});
for (var i in employees) {
var id = JSON.parse(localStorage.getItem(employees[i]));
}
Here is my code for the Edit button:
//register Edit button
$('.edit_button').live('click', function (e) {
alert('I was Cliked!');
e.stopPropagation();
$.each(employees, function(a, b) {
//if(b.id == employees[i]){
$('#id').val(b.id);
$('#employeeno').val(b.employeeno);
$('#employeename').val(b.employeename);
$("#stateoforigine").val(i.stateoforigine);
$('#employeephone').val(b.employeephone);
$('#dateofbirth').val(b.dateofbirth);
$("#id").attr("readonly","readonly");
$('#employeeno').focus();
$.mobile.changePage('#edit_employee_page');
return false;
//}
});
});
Here is my local Storage:
[
{"id":1,
"employeeno":"DEF/234/20014",
"employeename":"Bill Gates",
"stateoforigine":"Osun",
"employeephone":"080765432",
"dateofbirth":"12/11/1965"},
{"id":2,
"employeeno":"DEF/234/20014",
"employeename":"Bill Gates",
"stateoforigine":"Osun",
"employeephone":"080765432",
"dateofbirth":"12/11/1966"},
{"id":3,
"employeeno":"DEF/234/20014",
"employeename":"Bill Gates",
"stateoforigine":"Osun",
"employeephone":"080765432",
"dateofbirth":"12/11/1966"},
{"id":4,
"employeeno":"DAST/003/2003",
"employeename":"Gold Base",
"stateoforigine":"",
"employeephone":"",
"dateofbirth":"12/03/1986"}
]
Thanks for helping me out
The way you are storing your employees into localStorage is correct, but the way you are getting them out is incorrect. You stored your employees by stating:
localStorage.setItem("employees", JSON.stringify(employees));
So, in order to retrieve them, you must use:
var employees = JSON.parse(localStorage.getItem("employees"));
You see, you stored the data as a string with a key of "employees"; therefore, you can only retrieve it by that key. Since all data stored in localStorage is saved as a string, you must use JSON.parse() to convert the data back into an object - an array in this case. Then you can iterate over your employees.
Update:
You should be running this code as soon as the page is rendered (see below). I'm not sure how you're doing that - if you're using an IIFE or jQuery's document.ready() function. I don't think it's necessary to store an empty array into localStorage if none were loaded initially, so, I took your else clause out.
var employees = [];
if (localStorage.getItem('employees') !== null) {
employees = JSON.parse(localStorage.getItem('employees'));
}
Debug this line-by-line when it runs and make positive your employees variable contains data. If it doesn't contain data, well then, there's nothing to edit.
If, however, there is data, then execute your showEmployees() function. Oddly, I'm not seeing in your code where you actually call this. Is it bound to a button or action in your UI? Also, what is that for loop doing after your $('#edit_employee_page') click event function? It's trying to read data from localStorage improperly and it does nothing.
I think if you simply stepped through your code one line at a time using breakpoints and desk-checking your inputs/outputs you'd find out where you're going wrong.
It also appears that there's a disconnect in your code. May be you left out some lines; you define a string editEmployee but out of the blues you store JSON.stringify(employees) whereas employees is not defined in your code:
$('#edit_employee_page').on('click' , function(){
var editEmployee = JSON.stringify({
id: employees.length+1,
//........
});
//Alter the slected data
localStorage.setItem("employees", JSON.stringify(employees));
return true;
});
I had a similar task to do . I did it this way.
I passed the dynamic Id to be passed as an id attribute
id="'+empData.id+'"
and then inside the
$('.edit_button').live('click', function (e) {
alert('I was Cliked!');
var empId=$(this).attr('id');
rest of the code is same.

Categories

Resources