Parse.com iOS SDK: Create New Related Object on Object Save - database

I'm trying to use cloud code to create a new 'credit' every time a new User is created, the credit is for that user, as in it is a related object. For some reason I can't get writing to the 'Logs' tab to work using lines like console.log(tell me what is going on!); so I'm stumped, and with no way of knowing where I've gone wrong.
Parse.Cloud.afterSave("User", function(request) {
var Credit = Parse.Object.extend("credit");
var credit = new Credit();
credit.set("parent", request.object);
credit.set("expiry", null);
credit.set("type", "Opening");
credit.save();
});

You need to change it to this:
Parse.Cloud.afterSave(Parse.User, function(request)
Parse.User rather than "User".
For whatever reason this doesn't seem to be in the docs here: https://www.parse.com/docs/cloud_code_guide#functions-aftersave

Related

Meteor with query on publication is not reactive

I have a problem with a meteor publication not being reactive when using a query inside it.
Let's say I have many files, and each file has many projects, so I can go to the route:
http://localhost:3000/file/:file_id/projects
And I would like to both display the projects of the selected file and add new projects to it.
I am currently using angularjs, so the controller would look something like this:
class ProjectsCtrl {
//some setup
constructor($scope, $reactive, $stateParams){
'ngInject'
$reactive(this).attach($scope)
let ctrl = this
//retrieve current file id
ctrl.file_id = Number($stateParams.file)
//get info from DB and save it in a property of the controller
ctrl.subscribe('projects', function(){return [ctrl.file_id]}, function(){
ctrl.projects = Projects.find({file_id: ctrl.file_id}).fetch()
})
//function to add a new project
ctrl.addProject = function(){
if(ctrl.projectName){
Meteor.call('projects.insert', {name: ctrl.projectName, file_id: ctrl.file_id }, function(error, result){
if(error){
console.log(error)
}else{
console.log(result)
}
})
}
}
}
}
The publication looks something like this:
Meteor.publish('projects', function(file_id){
return Projects.find({file_id: file_id})
})
The problem is that, if I insert a new project to the DB the subscription doesn't run again, I mean the array stays the same instead of displaying the new projects I am adding.
I got many problems with this as I thought that meteor would work something like: "Oh there is a new project, let's re run the query and see if the publication change, if it does, let's return the new matching documents"... but no.
I have not found a problem similar to mine as every question regardind querys inside the publication is about how to reactively change the query (the file_id in this case) but that is not the problem here as I don't change the file_id unless I go to another route, and that triggers a new subscription.
My current solution is to expose the complete collection of projects and make the query using minimongo, but I don't know if it is a good workaround (many projects exposed uses too much memory of the browser, minimongo is not as fast as mongo... etc, I don't really know).
Your issue is that the Meteor.subscribe call doesn't know that file_id has changed. There's no reactive relationship between that argument and executing the subscription.
To fix this, whenever you are passing criteria in publish-subscribe, you must write a subscription of Collection inside a tracker.
To know more about trackers, Click here.
While I'm unsure how to do this in Angular, consider this simple Blaze template as an example:
Template.Name.onCreated(function(){
this.autorun(() => {
Meteor.subscribe('projects', file_id);
});
});
Whenever file_id changes, a new subscription is triggered, giving you the desired effect of auto pub-sub utility.
I hope this will give you some insight. It could be easily achieved via Angular JS as well.

Loki JS doesn't persist data in Ionic

I'm using LokiJS to save in local storage (well, I'm trying) .
What I want to do is a ToDo app, my controller is as follows:
.controller('Dash', function($scope) {
var db = new loki('loki.json');
$scope.name="";
$scope.lname="";
var users=db.getCollection('users');
if (users==null) {
$scope.message="It's null";
var users = db.addCollection('users');
}else{
$scope.message="It's ready";
}
$scope.insert=function(namesI, lnameI){
users.insert({
name: namesI,
lname:lnameI
});
}
The issue is that everytime that I test it, the message is "It's null". Although before already I have inserted data. I mean, everytime I launch the app, the database is created.
How I can persist the data?
*I'm not using any cordova plugin.
You are not providing a loadHandler function, so you are trying to access collections before Loki is finished loading the json file. Look at this example for a clarification on how to use the autoLoadHandler.
Also bear in mind that at some stage you need to call db.saveDatabase() to persist, or else you need to provide an autoSaveInterval value when instantiating Loki.

How to add to a list in Firebase without overwriting

I am trying to create a 'Favorites' section in my app where you hit a button and it is added to a user favorites list in firebase. I am using the ionic platform.
I created a factory to handle the favourites as they come in. and i use the getAuth() function to get the unique userID so i can just pull it when the user logs on. This is my attempt but i am not getting the result i wanted which is simply something like :
< userid >:
{
0: "fav1"
1: "fav2"
}
.factory('Favourites',function($firebaseArray){
var ref = new Firebase("https://experiencett.firebaseio.com/");
var authData = ref.getAuth();
var favs = $firebaseArray(new Firebase('https://experiencett.firebaseio.com/favourites/'+authData.uid+''));
return {
all: function() {
return favs;
},
add: function(){
var up=new Firebase('https://experiencett.firebaseio.com/favourites/');
var usersref=up.child(authData.uid);
usersref.push({3:"paria"});
},
When you call push() you are generating a unique id. While that is great for many use-cases, it is not good here since you want to control the path that is written.
Since you're already constructing the path with child(authData.uid) you can simply update it with update():
usersref.child(authData.uid).update({3: "paria"});
This will either update the existing value at 3 or write the new value for 3, leaving all other keys under /users/<uid> unmodified.
Alternatively if you want to replace the data that already exists at users/<users>, you can use set() instead of update().
This is all covered in the Firebase JavaScript SDK in the section on storing user data. It is not covered in the AngularFire documentation, since there is nothing specific to Angular about it.

Linking Data in Firebase

I am designing a forum and have a layout like this in on my Firebase:
root
|-posts
|-postID1
|-creator: "userOne"
|-creatorUID: "simplelogin:1"
|-text: "Some Text"
|-postID2
|-creator: "userTwo"
|-creatorUID: "simplelogin:2"
|-text: "Some Other Text"
|-profile
|-simplelogin:1
|-firstName: "John"
|-user: "userOne"
|-simplelogin:2
|-firstName: "Sue"
|-user: "userTwo"
On my forum page. I simply use a Angular ng-repeat to get all of the posts on Firebase and list them out. I also want to print out the first name of whoever created the post, but right now, I can only access {{ post.creator }}, which just gives the username of the person who posted. How can I link the post's creator (or creatorUID) with the first name field of that person's profile?
If you're just displaying the the users firstName I would place the users name in the postIDX object.
This would be quicker and produce less requests to Firebase with you going back and fourth with each post to get the usersFirst name.
more information on structuring data and best practices can be found here: https://www.firebase.com/docs/web/guide/structuring-data.html
Updated from response
if you wanted to get the user details then within every request to the postIDx you'd need to do something similar to this (not tested and quick mock up).
var fbRef = new Firebase('firebase path'),
postDetailsObject = {};
fbRef.child('posts').once('value', function(snapshot) {
// loop through each post
snapshot.forEach(function(childSnapshot){
var postDetails = childSnapshot.val(),
profileDetails;
postDetailsObject.post = postDetails;
fbRef.child('profile/' + postDetails.creatorUID).once('value', function(profileData) {
postDetailsObject.profile = profileData;
});
})
});
Then return the postDetailsObject in to angular so you can loop through the single object.

AngularFire equivalent to $setPristine?

I'm trying to understand the correct workflow to create a $setPristine equivalent with my Firebase data.
My workflow is as follows:
1) Create Firebase object (via the Angularfire Generator 'SyncData')
2) Form data modifies the $firebase object.
3) To update the remote model, I use myRef.$save()
All of that works well. Now, I'm trying to add a "reset" button on the form, so that the locally modified data will revert back to the remotely stored data.
So far, I'm running into problems. I've tried reinitializing the firebase reference eg myRef = syncData('/my/path') but not only does that now work, but it is destroying the remote data object!
What is the correct way to re-pull the remote data to use in my Angular model?
I know this is an old question, but I ran into this issue myself.
After some searching around I found this post: http://grokbase.com/t/gg/firebase-angular/1499haaq4j/editing-data-as-a-copy
Which led me to an outdated code snippet (2 months lol XD) from #Kato: https://gist.github.com/katowulf/8eaa39eab05a4d975cd9
I modified this to work with Firebase 2.3.1 and AngularFire 1.1.3:
app.factory('ResetFactory', function($firebaseArray) {
return $firebaseArray.$extend({
reset: function(itemOrIndex) {
var key, self;
self = this;
key = self.$keyAt(itemOrIndex);
self.$ref().child(key).once('value', function(snap) {
self.$$updated(snap);
});
}
});
});
Which can be called via:
var comments = new RevertFactory(ref.child('comments'));
# variable comment is for example an ng-repeat that's being edited
comments.reset(comment);

Resources