I need to get Google Drive a folder's fileId. If the folder does not exist, I need to create a folder with that name and return fileId. With fileId, I need to do other works.
The Google Drive API in Dart is ok for me, I can create a folder with Dart. The question is about Future.
The code is as follow:
drive.files.list(q:"title='TEST'").then((result){
if(result.items.length == 0) {
driveclient.File file = new driveclient.File.fromJson({"title":"TEST", "mimeType": "application/vnd.google-apps.folder"});
drive.files.insert(file).then((result2) {
return result2.id;
});
} else {
return result.items[0].id;
}
});
When TEST exists, the id is returned. But if TEST doesn't, the function error because no return.
How to do that?
Thanks in advance.
You need to return the future from the then method you call in line 4:
drive.files.list(q:"title='TEST'").then((result){
if(result.items.length == 0) {
driveclient.File file = new driveclient.File.fromJson({"title":"TEST", "mimeType": "application/vnd.google-apps.folder"});
return drive.files.insert(file).then((result2) {
return result2.id;
});
} else {
return result.items[0].id;
}
});
then() returns a new future there completes with the value returned from the method you give as parameter to the method. then() is also smart enough to resolve all nested future's so you will always handle a value inside a then() method and never a instance of Future.
Related
I built a simple plugin that shows in the CRMContainer the url of my CRM given some attributes parameters (if they are passed by), during inbound tasks this works fine, but the problem is that during outbound calls the behaviour is not the one expected, this is the piece of code:
flex.CRMContainer.defaultProps.uriCallback = (task) => {
return task
? `https://mycrm.zzz/${task.attributes.clicar}/${task.attributes.contacth}/`
: 'https://mycrm.zzz/contacts/';
}
}
I would need an additional condition that tells the code, if this is an outbound voice call to always show a default url.
I tried adding an if/else that checks if task.attributes.direction is outbound, but Flex says this is undefined.
Any tip?
Thanks
Max
The problem is that you aren't checking for the existence of the task. Your original code had this:
flex.CRMContainer.defaultProps.uriCallback = (task) => {
return task
? `https://mycrm.zzz/${task.attributes.clicar}/${task.attributes.contacth}/`
: 'https://mycrm.zzz/contacts/';
}
}
Which returns the URL with the task attributes in it only if the task exists, because of the ternary conditional.
So, when you try to use the attributes you need to make sure the task exists. So taking your code from the last comment, it should look like this:
flex.CRMContainer.defaultProps.uriCallback = (task) => {
if (task) {
if (task.attributes.direction === 'outbound'){
return `https://mycrm.zzz/${task.attributes.clicar}/${task.attributes.contacth}/`;
} else {
return `https://mycrm.zzz/contacts/`
}
} else {
return 'https://mycrm.zzz/contacts/';
}
}
I have problems with returning a message in Jira out of Java.
I made a plugin, overwriting the CreateWorklog class (the doExecute() method) when creating an issue.
After my functionalities the method ends with those lines:
[...]
if (NONE.equals(superResult))
{
return returnMsgToUser(getReturnUrl(), messageToUser, MessageType.SUCCESS, true, null);
}
return superResult;
And before that, there are some options to return before creating the issue, those look like this for example:
[...]
if (httpPostReq.getResponseCode() != 201)
{
System.out.println("ERROR: Webservice-Aufruf fehlgeschlagen! Response-Code: " + httpPostReq.getResponseCode());
return returnMsgToUser(getReturnUrl(), "ERROR: Webservice call failed! Response-Code: " + httpPostReq.getResponseCode(), MessageType.ERROR, true, null);
}
[...]
The return argument makes the method cancels the issue-creation, but the return message is not as wanted.
First, the normal return message of the unchanged function appears, but after reloading the website, my own message appears.
Why it's only visible after refreshing the Jira website? How could I change that behavior?
And another question:
What exactly is the String target (last constructor parameter) doing in returnMsgToUser? The only information I could find, is that if you put in null, it's placed in a global spot. And what else could you put in there? I have no ideas...
If I pass hard coded values in offerCheck validator it is working fine. But if I get values from api, null values is getting passed in paramets. Form is getting executed before we get the values from service. Please help me to make validate check after getting values from api.
this.newOffer = "aaa";
this.oldOffer = "aaa";
constructor(fb: FormBuilder) {
this.formGroup = fb.group({
'offer': [null, Validators.compose([Validators.required, this.offerCheck(newOfer, oldOffer)])],
})
offerCheck(new, old) {
return (control: FormControl) => {
if (new == old) {
return true;
}
}
}
What you want is probably the AsyncValidatorFn, here's a very simple example of how to create one:
export const OfferCheck: AsyncValidatorFn = (control: AbstractControl): Observable<boolean> => {
if (new == old) {
return Observable.of(this.http.get('/some-endpoint').first().map(res => res.data));
}
};
You don't provide enough information so this is just a guess on how you'd want it to be. But it should point you in the right decision.
An alternative method would be to use setValidators of the control(s) after you've fetched the data:
this.formGroup.get('offer').setValidators([Validators.required, this.offerCheck(newOfer, oldOffer)]);
I hope this helps.
I use my postgres database query to determine my next action. And I need to wait for the results before I can execute the next line of code. Now my conn.query returns a Future but I can't manage to get it async when I place my code in another function.
main() {
// get the database connection string from the settings.ini in the project root folder
db = getdb();
geturl().then((String url) => print(url));
}
Future geturl() {
connect(db).then((conn) {
conn.query("select trim(url) from crawler.crawls where content IS NULL").toList()
.then((result) { return result[0].toString(); })
.catchError((err) => print('Query error: $err'))
.whenComplete(() {
conn.close();
});
});
}
I just want geturl() to wait for the returned value but whatever I do; it fires immediately. Can anyone point me a of a piece of the docs that explains what I am missing here?
You're not actually returning a Future in geturl currently. You have to actually return the Futures that you use:
Future geturl() {
return connect(db).then((conn) {
return conn.query("select trim(url) from crawler.crawls where content IS NULL").toList()
.then((result) { return result[0].toString(); })
.catchError((err) => print('Query error: $err'))
.whenComplete(() {
conn.close();
});
});
}
To elaborate on John's comment, here's how you'd implement this using async/await. (The async/await feature was added in Dart 1.9)
main() async {
try {
var url = await getUrl();
print(url);
} on Exception catch (ex) {
print('Query error: $ex');
}
}
Future getUrl() async {
// get the database connection string from the settings.ini in the project root folder
db = getdb();
var conn = await connect(db);
try {
var sql = "select trim(url) from crawler.crawls where content IS NULL";
var result = await conn.query(sql).toList();
return result[0].toString();
} finally {
conn.close();
}
}
I prefer, in scenarios with multiple-chained futures (hopefully soon a thing of the past once await comes out), to use a Completer. It works like this:
Future geturl() {
final c = new Completer(); // declare a completer.
connect(db).then((conn) {
conn.query("select trim(url) from crawler.crawls where content IS NULL").toList()
.then((result) {
c.complete(result[0].toString()); // use the completer to return the result instead
})
.catchError((err) => print('Query error: $err'))
.whenComplete(() {
conn.close();
});
});
return c.future; // return the future to the completer instead
}
To answer your 'where are the docs' question: https://www.dartlang.org/docs/tutorials/futures/
You said that you were trying to get your geturl() function to 'wait for the returned value'. A function that returns a Future (as in the example in the previous answer) will execute and return immediately, it will not wait. In fact that is precisely what Futures are for, to avoid code doing nothing or 'blocking' while waiting for data to arrive or an external process to finish.
The key thing to understand is that when the interpreter gets to a call to then() or 'catchError()' on a Future, it does not execute the code inside, it puts it aside to be executed later when the future 'completes', and then just keeps right on executing any following code.
In other words, when using Futures in Dart you are setting up chunks of code that will be executed non-linearly.
The xpages contain SAVE button. The xpages also contain InternetAddres field.
When user click SAVE button, need to check first on names.nsf
- Save success if InternetAddress value NOT found in names.nsf view "($Users)"
- Save fail if InternetAddress value found in names.nsf view "($Users)"
How to write the script to do that?
This is the LotusScript version of script:
Set namesview = namesdb.GetView( "($Users)" )
Set namesdoc = namesview.GetDocumentByKey( Lcase(doc.CurrentInternetAddress( 0 ) ), True )
If ( namesdoc Is Nothing ) Then '-- Create New Doc
How to move on xpages?
The latest release of the OpenNTF Domino API adds a checkUnique() method to the View class. It takes two parameters, the first being a key to check against the view (e.g. a String or List of Strings), the second being the current document. After all, if you're checking for a pre-existing document, you don't want to fail just because it finds this document in the view.
So assuming CurrentInternetAddress is a single value field, the code would be:
function continueWithValidUser(namesDB, doc) {
var success = false;
try {
var view = namesDB.getView("($Users)");
success = view.checkUnique(doc.getItemValue("CurrentInternetAddress"),doc);
} catch (e) {
print(e.message);
}
return success;
}
OpenNTF Domino API recycles all handles to Domino objects, so the recycle() calls aren't needed.
In your datasource is a querySave event. You write JS there. It is almost the same code. Just with { } and ;
Remarks:
your app will break when there is more than one address book, so you you would want to use #NameLookup which is quite fast and checks all addressbooks.
unless you need the document getEntry is faster than getDocument
In SSJS your function would look like this:
function continueWithValidUser(namesDB, addressCandidate) {
var success = false;
try {
var view = namesDB.getView("($Users)");
var doc = view.getDocumentByKey(addressCandidate);
success = (doc != null);
doc.recycle();
view.recycle();
} catch (e) {
print(e.message);
}
return success;
}
That should do the trick