The raw results returned from Parse.com are shown in the console as [child, child].
I imagine this means that there are three levels to this object? So in order to access in the first ng-repeat do I need to do a foreach in the controller before pushing to an array and then use that in $scope... seems a long way around to get what i want.
Is it possible to use the raw results from Parse.com in the scope. I would like to do this:
var query = new Parse.Query("Programme");
query.equalTo("userId", userId);
query.find()
.then(function(result){
$scope.programmes = result;
console.log($scope.programmes);
});
However this gives me the child elements - do I have to foreach, or is there some angular trickery?
You are able to perform Parse.Object's get function within the view.
So I changed things to be
{{programme.get('title')}}
Credit for this is from here
The marked answer is not working any more
The proper way is to extend the object and then map the values back to whatever items you need in that class.
Then you can bind in normally to ng-repeat without changing your html code specifically for Parse.
var Game = Parse.Object.extend("Game");
var query = new Parse.Query(Game);
query.find({
success: function(results) {
$scope.$apply(function() {
$scope.games = results.map(function(obj) {
return {points: obj.get("points"), gameDate: obj.get("gameDate"), parseObject: obj};
});
});
},
error: function(error) {
console.log(error);
}
Related
I'm building this website: http://collections.design
The way it works is by reading all tools data from a JSON, using jQuery (I don't know much javascript). Then, you can click on an item and a side panels opens with further information. But there's a lot of repeated code, so I'm trying to optimise it a bit.
First I parse the JSON:
// The data source
var data_source = "../data/tools/tools.json";
// Parsing the JSON
$.getJSON(data_source, function(data) {
$.each(data, function(key,val) {
// And I'm storing all of its values in variables, to make them easier to read:
var name = val.availability.name;
var linux = val.os.linux;
// Then I'm using all that to render each item on screen
…
});
});
Each of the items has a button that calls another function to create and open the side panel. The side panel reuses that item's data from the JSON. This function to create the side panel is using the name variable as parameter, but then inside is parsing the JSON again to get the rest of the values it needs.
My question is:
How can I "encapsulate" all variables when I do the JSON parsing, then pass it as a parameter to the other function; and finally, individually read each of those values in the other function?
I tried working with arrays. But didn't manage it to work, also keeping in mind that I'm trying to simplify things, not repeat myself, and keep short names…
Maybe I'm asking too much, but any pointers or links to doc will be appreciated.
I see two ways of doing this.
1) Save the JSON data outside the scope so you can reuse it and pass the index of the data you want.
Something like this
// The data source
var data_source = "../data/tools/tools.json";
var all_data;
// Parsing the JSON
$.getJSON(data_source, function(data) {
all_data = data;
$.each(data, function(key,val) {
$('.button').on('click', function() { callToOtherFunction(key) })
});
});
function callToOtherFunction(key) {
console.log(all_data[key]);
}
2) As Sam Axe said, pass the data directly to the function
// The data source
var data_source = "../data/tools/tools.json";
// Parsing the JSON
$.getJSON(data_source, function(data) {
$.each(data, function(key,val) {
$('.button').on('click', function() { callToOtherFunction(key) })
});
});
function callToOtherFunction(val) {
console.log(val);
}
Here's a working fiddle.
The data is already "encapsulated" in the data object. Pass that object to the function that you want to use the data in.
You could always construct a new object - but what's the point - it's already in the data object.
There is an existing Parse.com class that needs to be copied to a new Parse.com class with some new columns and the transformation of one of the columns. The code currently works and uses the Parse.Query.each method to iterate over all records as detailed in the Parse.com documentation but it stops processing at 831 records although there are 12k+ records in the class. This is odd given each should not have a limit and other default limits are 100 or 1000 for find. Should another method be used to iterate over all records or is there something wrong with the code?
var SourceObject = Parse.Object.extend("Log_Old_Class");
var source_query = new Parse.Query(SourceObject);
var TargetObject = Parse.Object.extend("Log_New_Class")
source_query.each(function(record) {
//save record to new class code works fine
var target_query = new TargetObject();
target_query.set("col1_new",record.col1);
target_query.set("col2_new",record.col2);
//etc...
target_query.save(null, {
success: function(obj) {
//SAVED
},
error: function(obj, error) {
//ERROR
}
});
}).then(function() {
//DONE
},
function(error) {
//error
});
One thing that comes to my mind immediately is that the function is getting timed-out. Parse has time limitations on each function. If I were you, I'd first load all the objects in the source class and then add them separately by having a delay between to API calls (server overload issues can also be present).
I have a list of request to make to Parse.com using the swif API for tasks acumulated once the application was offine. Some tests show that if I dowload it all at once the overall time is slow that is I use multiple requests. However I couldn't figureout how can I request many "random" objectId's from Pase.com (I have a list of course, by random I mean out of order and not a fix number)
At the moment I am using a loop and calling many:
let pred = NSPredicate(format: "newDataID = %#, dataID[i])
query.findObjectsInBackgroundWithBlock { (result:[AnyObject]?, error:NSError?)
I was thinking in auto generate the string for the predicate but it can get very long what I image would make the query very slow.
Any ideas?
Under any circumstances, initiating many requests in a tight loop is ill-advised. Instead, send the dataID array to a cloud function. Also, if its really an array of object ids, then find is the wrong method, use get() instead...
var _ = require('underscore'); // underscore includes many handy functions, including map and toArray
Parse.Cloud.define("getManyObjectsById", function(request, response) {
var dataID = request.params.dataID;
var promises = _.map(dataID, function(anID) {
var query = new Parse.Query("MyCustomClassName");
return query.get(anID);
});
Parse.Promise.when(promises).then(function() {
response.success(_.toArray(arguments));
}, function(error) {
response.error(error);
});
});
Call it...
PFCloud.callFunctionInBackground("getManyObjectsById", withParameters: dataID) {
(objects: [AnyObject]?, error: NSError?) -> Void in
// objects should be an array of objects corresponding to the ids
}
In my cloud code I want to retrieve the first object in the "Messages" class. Then i want to grab some information from that object, send it to another class, and finally delete that object from the "Messages" class i originally pulled it from.
My question is do i need to query the entire "Messages" class just to get the first object in it? I don't want to slow down my app due to inefficient code.
Parse.Cloud.afterSave("sendMessage", function(Parse.Message, response) {
var body = null;
var senderName = null;
var senderId = null;
var randUsers = [];
var query = new.Parse.Query(Parse.Message);
query.find({
success: function(results){
body.push(results[1].get("messageBody"));
senderName.push(results[1].get("senderName"));
senderId.push(results[1].get("senderId"));
response.success(getUsers);
},
error: funtion(error){
response.error("Error");
}
});
});
to avoid confusion: "getUsers" is an arbitrary function call.
To retrieve entry from class, you need the query the table. However, your problem is getting the first record which does not require getting the all record. From your code I can see that you get the first record of result array (result[1] ). You can apply the solution; getting the first record of the class that you want to query. You can do it via two ways; either you can set the limit 1 to your query or you can use the first() method. The Parse.Query JS API link is below;
https://parse.com/docs/js/symbols/Parse.Query.html
Check the limit and first methods.
Hope this helps.
Regards.
I make a query from parse.com angd get and array of 2 object. Now I want to user ng-reapet('phone in phones') , so I need to convert it to json. I didn't suucess to do it. for some reason, it doesnt see the result as a json.
var Project = Parse.Object.extend("Project");
var query = new Parse.Query(Project);
query.find({
success: function (results) {
var allProjects = [];
for (var i = 0; i < results.length; i++) {
allProjects.push(results[i].toJSON());
}
$scope.phones = allProjects;
//i also tried this : $scope.phones = JSON.stringify(allProjects);
},
error: function (error) {
alert("Error: " + error.code + " " + error.message);
}
});
Thanks
Not sure if you already figured this out, but I was having a similar issue and found your post. I'm not sure what your HTML looks like, but I ended up using the Parse.Object's get method in my repeater like so:
<ul ng-repeat="list in lists">
<li>
<a ng-href="#/lists/{{list.id}}">{{list.get('title')}}</a>
</li>
</ul>
I also looked into using promises so that the Parse query success callback actually updates the view when you set $scope.phones to the query result. My code is similar to yours but my object is List instead of Project. Here is what mine looks like:
// Define your Parse object
var List = Parse.Object.extend('List');
// Define a function that runs your Parse query. Use an angular promise so that
// the view updates when you set your $scope var equal to the query result
function getList() {
var deferred = $q.defer();
var query = new Parse.Query(List);
query.find({
success: function(results) {
deferred.resolve(results);
},
error: function(error) {
deferred.reject(error.message);
}
});
return deferred.promise;
}
// Call the getList function on load
var promise = getLists();
promise.then(function(lists) {
$scope.lists = lists;
});
So basically, it isn't that Angular doesn't see the response right. You shouldn't have to modify the result from Parse in any way. It's just that you need to use the Parse.Object get method like you would if you were accessing properties of the object, and make sure that you are using a promise so that Angular accesses your query result as it should in the view.
Do not use .get function on Parse in you angular code, its not working any more, plus its not a good idea to change your angular code because your object is three level nested and need a get method.
The proper way is to extend the object and then map the values back to whatever items you need in that class.
Then you can bind in normally to ng-repeat without changing your html code specifically for Parse.
var Game = Parse.Object.extend("Game");
var query = new Parse.Query(Game);
query.find({
success: function(results) {
$scope.$apply(function() {
$scope.games = results.map(function(obj) {
return {points: obj.get("points"), gameDate: obj.get("gameDate"), parseObject: obj};
});
});
},
error: function(error) {
console.log(error);
}
There may be better tools , frameworks to use.
line 188 is the fetch. It automatically loads json for the model into the collection defined at line 47.
Looping over entries in the result from the query on parse is all automated in the framework so that you can save yourself tons of time by learning a relevant framework ( ie backbone ). On backbone/parse you focus on business logic , not manipulating network io and query structures.
'phone in phones' from your question may just be a nested model or nested collection which IMO can be handled by more advanced manipulation of the basic backbone framework.