How to return an array of ParseObject from CloudCode call - unity3d

There is a parse CloudCode function created as such:
Parse.Cloud.define("getCurrentEvents", function(request, response) {
var TimedEvent = Parse.Object.extend("TimedEvent");
var query = new Parse.Query(TimedEvent);
query.greaterThan("expiresOn", new Date());
query.find({
success: function(results) {
response.success(results);
},
error: function(error) {
response.error("There was an error while looking for TimedEvents");
}
});
});
It returns an array of TimedEvent, as shown in the curl test here:
{"result":[{"expiresOn":{"__type":"Date","iso":"2014-07-31T22:31:00.000Z"},"playMode":"Normal","tableId":"Carnival","objectId":"J1LSO3EnKi","createdAt":"2014-07-28T21:48:22.983Z","updatedAt":"2014-07-28T22:32:14.304Z","__type":"Object","className":"TimedEvent"}]}
When trying to access it from Unity SDK however, I get a "cannot convert to destination type" exception with the following line:
System.Threading.Tasks.Task<Parse.ParseObject[]> task =
Parse.ParseCloud.CallFunctionAsync<Parse.ParseObject[]> ("getCurrentEvents", parameters);
I also tried
System.Threading.Tasks.Task<IEnumerable<Parse.ParseObject>> task =
Parse.ParseCloud.CallFunctionAsync<IEnumerable<Parse.ParseObject[]>> ("getCurrentEvents", parameters);
with the same (lack of) results. What kind of signature is the SDK expecting?

Have you tried something like this (without IEnumerable?):
Threading.Tasks.Task<Parse.ParseObject> task = Parse.ParseCloud.CallFunctionAsync<Parse.ParseObject>("getCurrentEvents", parameters);
But better yet, you could extend ParseObject to create your own TimedEvent class in Unity, like this:
[ParseClassName("TimeEvent")]
public class TimeEvent : ParseObject
{
[ParseFieldName("expiresOn")]
public DateTime expiresOn
{
get { return GetProperty<DateTime>("expiresOn"); }
set { SetProperty(value, "expiresOn"); }
}
[ParseFieldName("playMode")]
public string playMode
{
get { return GetProperty<string>("playMode"); }
set { SetProperty(value, "playMode"); }
}
[ParseFieldName("tableId")]
public string tableId
{
get { return GetProperty<string>("tableId"); }
set { SetProperty(value, "tableId"); }
}
// any other fields you want to access
}
Then you can query your data like this:
IEnumerator getTimedEvents(Dictionary<string, object> parameters)
{
var cloudTask = Parse.ParseCloud.CallFunctionAsync<TimeEvent>("getCurrentEvents", parameters);
while (!cloudTask.IsCompleted)
yield return null;
if (cloudTask.IsCanceled || cloudTask.IsFaulted)
{
// handle error
}
else
{
TimeEvent t = cloudTask.Result;
// do stuff with t
}
}
P.S. Don't forget to register your Parse class somewhere (I usually do it in the Awake() of an early GameObject). In your case, you would do it like this:
Parse.ParseObject.RegisterSubclass<TimedEvent>();

Related

What should I do to get database response from this vertx code

This is the method used for database connection and obtain results:
public Future<String> getDatabaseUsers(JDBCClient client) {
return Future.future(pHandler -> {
client.getConnection(res -> {
if (res.succeeded()) {
SQLConnection con = res.result();
con.query("select u.id, u.name from users u", rHandler -> {
String data;
if (rHandler.succeeded()) {
data = Json.encode(rHandler.result().getResults());
} else {
data = "Database execution error";
}
con.close();
pHandler.complete(data);
});
} else {
pHandler.complete("Cannot connect to database");
}
});
});
}
This is the caller method:
private void handleRequest(RoutingContext routingContext, JDBCClient client,
Handler<List<String>> resultHandler) {
routingContext.vertx().<String>executeBlocking(pHandler -> {
pHandler.complete(getDatabaseUsers(client).result());
}, ar -> {
List<String> responses = new ArrayList<>();
if (ar.succeeded()) {
responses.add(ar.result());
System.out.println(Json.encode(responses)); // Null here
}
resultHandler.handle(responses);
});
}
The resultHandler object is used to add more responses from other processes; but this is not the problem actually.
And this is the endpoint:
router.get("/db").handler(ctx -> handleRequest(
ctx, client, (list) -> ctx.response()
.putHeader("Content-Type", "text/plain")
.end(Json.encode(list))));
The problem with this code, is that service response is [null] and the database method is not accomplished yet.
So, what should I do to wait for database response and then send the response to the client?
There are a number of issues with this code:
getDatabaseUsers swallows errors. You probably want to do pHandler.fail(res.failure()); or something similar.
This code: pHandler.complete(getDatabaseUsers(client).result()); is not doing what you think it's doing. result() doesn't block, so you complete your future with another unfishined future.
What you actually want is the reverse:
getDatabaseUsers(client).handle((r) -> { // This is called when the futures actually completes
if (r.succeeded()) {
pHandler.complete(r.result());
}
...
});
I would really recommend going over this guide, as it covers exactly your case.

jasmine: Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.. When i am trying get a non present element

When I am trying to check presence of not presented element/ button. I am getting:
Jasmine timeout exception
My code like
getName(): any {
let name = element(by.id("xxxxxx"));
return name.isPresent().then((ispresent) => {
if (ispresent) {
return name.getText();
} else {
return '';
}
})
}
I am trying to access that method expect(method).toequal('');
It should run, because if not present i am expecting empty string but i am getting Jasmine timeout.. I didn't added any waits any where.
isPresent()
From the GitHub repo, ElementFinder.isPresent
isPresent(): wdpromise.Promise<boolean> {
return this.count().then((count) => {
return count > 0;
});
}
isPresent checks for a count, but does not catch if there is an error. If the count throws, we should probably return 0. Getting a text for an element that does not exist should also have throw a promise rejection.
Note: It might be better to change your method to async / await (optional).
async getName(): webdriver.promise.Promise<string> {
const name = element(by.id("xxxxxx"));
try {
return name.getText();
} catch (e) {
return '';
}
}
Or not async / await
getName(): webdriver.promise.Promise<string> {
const name = element(by.id("xxxxxx"));
return name.getText().catch(e) {
return '';
}
}
Try the below one
async getName() {
let name = element(by.id("xxxxxx"));
let value: string = '';
await name.ispresent().then((ispresent) => {
if (ispresent) {
value=name.getText();
}
});
return value;
}
Hope it helps you

How can I DRY up my service in Angular 2

I'm working on a Angular 2 service and I'm trying to DRY up my code. My service returns data from an RESTful API (GET request). For the moment i only send one param (auth_token) but how can i deal with a call to my service with extra params ?
Here my basic call to my service:
this._dashboardService.getData('users')
.subscribe(usersData=> {
if (usersData.ok) {
this.users= usersData.json();
});
Here is my service :
getData(data) {
let authToken = localStorage.getItem('auth_token');
let params = new URLSearchParams();
params.set('auth_token', authToken);
return this._http
.get(this._url+data,{ search: params })
.map(data=> {
if (data.status===200) {
return data;
}
});
}
I want to make this code work :
this._dashboardService.getData('users',oneParameter)
.subscribe(usersData=> {
if (usersData.ok) {
this.users= usersData.json();
});
I'm not sure how to proceed to make this (is it even possible ?)
Any ideas ?
You can pass your new object param and assign to another object that contains the auth_token.
getData(data, anotherParams) {
let params = new URLSearchParams();
let authToken = localStorage.getItem('auth_token');
var myObject = Object.assign({'auth_token':authToken}, anotherParams);
for (var name in myObject) {
params.set(name, myObject[name]);
}
return this._http
.get(this._url+data,{ search: params })
.map(data=> {
if (data.status===200) {
return data;
}
});
}

Cannot read property 'subscribe' of undefined in nested calls in Angular 2

I want to subscribe in company-list.component on getCompanies() from the company.service. However I get the following error:
Cannot read property 'subscribe' of undefined
This is the code:
company.service.ts
getCompaniesOfUser() {
let r;
this.userService.getUser().subscribe(
res=> r = res,
err => console.log(err),
()=>(this.getCompaniesWithSpecificLink())
)
}
getCompaniesWithSpecificLink() {
if (isAdmin == false) {
url = '/user/companies';
} else {
url = '/companies';
}
return this.getCompanies(url);
}
getCompanies(url):Observable<Company[]> {
return this.http.get(this.host + url)
.map((res:Response) => res.json());
}
company-list.component.ts
companies:Company[];
public getTheCompanies() {
this._companyService.getCompaniesOfUser()
.subscribe(companies => this.companies = companies); <-- the error occurred here
}
Subscribe method must be used on an observable but your getCompaniesOfUser() method is not returning anything thus is a void method.
If you want to call back-to-back rest services. Like one's input depending on the others' output. You should use the flatMap operator.
Check this answer for example: https://stackoverflow.com/a/36712707/5706293
Something like this should work:
getCompaniesOfUser() {
return this.userService.getUser().flatMap( (resp) => {
return this.getCompaniesWithSpecificLink();
});
}

sails.js the return object from service is undefined when using a find query

I created a service called AppService.
Its function getUserPostionOptions is supposed to return an object:
getUserPostionOptions: function (user) {
// PositionOptions.findOne({id:'53f218deed17760200778cfe'}).exec(function (err, positionOptions) {
var positionDirectionsOptions = [1,2,3];
var positionLengthsOptions = [4,5,6];
var object = {
directions:positionDirectionsOptions,
lengths:positionLengthsOptions
};
return object;
// });
}
This works, in my controller positionOptions gets populated correctly:
var positionOptions = AppService.getUserPostionOptions(user);
However, when I uncomment the find query the item is found but the object returns undefined.
Thank in advance for your help
SailsJs ORM (and almost NodeJs database querying methods) uses non-blocking mechanism via callback function. So you have to change your code into:
getUserPostionOptions: function (user, callback) {
PositionOptions.findOne({id:'53f218deed17760200778cfe'}).exec(function (err, positionOptions) {
var positionDirectionsOptions = [1,2,3];
var positionLengthsOptions = [4,5,6];
var object = {
directions:positionDirectionsOptions,
lengths:positionLengthsOptions
};
callback(null, object); // null indicates that your method has no error
});
}
Then just use it:
AppService.getUserPostionOptions(user, function(err, options) {
if (!err) {
sails.log.info("Here is your received data:");
sails.log.info(options);
}
});