I just followed the API docs and made simple query using JS API
and getting an error 400: Invalid Value of the nextPageToken
gapi.load('client', function(){
gapi.client.load('drive', 'v3', function(){
gapi.client.init({}
).then(function(){
gapi.client.drive.files.list({
'q' : "name contains 'nv'",
'pageSize' : 10,
'fields' : "nextPageToken, files(id, name, webContentLink, folderColorRgb, thumbnailLink, description)",
'orderBy' : 'modifiedTime desc',
}).then(function(respo){
var token = respo.result.nextPageToken;
gapi.client.drive.files.list({
'fields' : '*',
'pageToken' : token
}).then(function(result){console.log(result.result);})
})
})
})
})
Token returned from first query is ok, getting it full.
But in the next query it's becomes wrong.
Didn't find a format for the token, so I cannot check if it's good or?!
p.s. tested developers console, getting the token and in the next query getting same error.
I have found that the subsequent page request must have the same 'q' value of the first request to avoid getting the HTTP 400 error. For example, if the first request is:
gapi.client.drive.files.list({
'q' : "name contains 'nv'",
'pageSize' : 10,
'fields' : "nextPageToken, files(id, name)"
}).then(function(respo){
...
}
The subsequent request must also have the same 'q':
gapi.client.drive.files.list({
'q' : "name contains 'nv'",
'pageToken' : nextPageToken,
'pageSize' : 10,
'fields' : "nextPageToken, files(id, name)"
}).then(function(respo){
...
}
Make sure to always check the validity of nextPageToken as feeding a null value on subsequent request will restart the list operation all over again.
I simply don't believe this!!!
Google makes such stupid things.
The problem is that it needs to be written in next query not pageToken, but nextPageToken and it's working.
Checked couple times, it does.
In docs it's written wrong and also in their console.
Shame!
This is the top result I have found for attempting to do pagination within a Google Drive JavaScript operation. They should just show an example on their documentation, but I could not find it there. Facebook had that example however. Anyway, to do paging in their framework:
//Global variable to hold token pointer
var NextPageToken = '';
function GetFiles() {
gapi.client.drive.files.list({
'pageSize': 25,
'q': "mimeType contains 'image/'",
'fields': "nextPageToken, files(id, name)"
}).then(function (response) {
var files = response.result.files;
// if response.result.nextPageToken exists, use it
if (response.result.nextPageToken) {
NextPageToken = response.result.nextPageToken;
} else {
NextPageToken = false;
}
});
}
function GetNextSetOfImages() {
gapi.client.drive.files.list({
'pageSize': 25,
'q': "mimeType contains 'image/'",
'pageToken': NextPageToken,
'fields': "nextPageToken, files(id, name)"
}).then(function (response) {
var files = response.result.files;
// if response.result.nextPageToken exists, use it
if (response.result.nextPageToken) {
NextPageToken = response.result.nextPageToken;
} else {
NextPageToken = false;
}
});
}
Related
I am trying to access Restlet from User Event script but i am receiving error: body":"error code: INVALID_LOGIN_ATTEMPT\nerror message: Invalid login attempt. Do i need to pass credentials too? what should i pass client id, client secret? is there another way?
I also tried url.resolveScript but no luck.
/**
* #NApiVersion 2.x
* #NScriptType UserEventScript
* #NModuleScope Public
*/
define(["N/https", "N/log", "N/record", "N/url" ],
function(https, log, record, url) {
function beforeLoad(context) {
// log.debug('beforeLoad Triggered');
// context.newRecord;
// context.type;
// context.form;
return;
}
function afterSubmit(context) {
log.debug('Before code');
var record = context.newRecord;
var requestBody = {
"recordId": record.id,
"recordType": record.type,
};
var output = url.resolveScript({
scriptId: '1157',
deploymentId: '1',
});
var output1 = 'https://12345-sb5.restlets.api.netsuite.com';
log.debug('After code', output );
var response = https.post({
url: output1 + output,
body: requestBody,
});
if (response.code === 200) {
// success!
} else {
// handle error
}
log.debug('After code', response );
return;
}
function beforeSubmit(context) {
// log.debug('beforeSubmit Triggered');
// context.newRecord;
// context.oldRecord;
// context.type;
return;
}
return {
beforeLoad : beforeLoad,
afterSubmit : afterSubmit,
beforeSubmit : beforeSubmit
}
})
Why do you need your UE Script to submit and trigger your RESTlet every record submit?
Below could work for ClientScript, just not sure if saveRecord (only when the Submit/Save is clicked) entry point will trigger this.
var requestBody = JSON.stringify({
recordId: record.id,
recordType: record.type
});
var output = url.resolveScript({
scriptId: '1157',
deploymentId: '1'
});
var response = https.post({
url: output,
body: requestBody
});
Previously you could manipulate the cookies and pass it. However, it's no longer the case and Server Scripts cannot call Server Scripts unless you pass Authentication which is a pain if you have no library. Oauth1 + SHA256 is complicated to figure out without libraries.
You could probably approach this on another angle depending on your use case. At this moment, it isn't clear why you want AfterSubmit to call RESTlet. If you do this, if you have routine Scheduled Scripts that touches that record and saves the record, it will keep triggering your AfterSubmit unless you place an if statement.
try https.requestRestlet
var response = https.requestRestlet({
body: JSON.stringify({
"recordId": record.id,
"recordType": record.type,
}),
deploymentId: '1',
method: 'POST',
scriptId: 1157,
});
I am using Google's GMail API to get the number of unread emails (and list them) in my email account.
I have the code straight out of Google's sample (below). Console returns: "Cannot read property 'gmail' of undefined". I have found nothing that states that gmail must be defined. What am I missing?
var query = "is:unread";
var userId = "me";
function listMessages(userId, query, callback) {
var getPageOfMessages = function(request, result) {
request.execute(function(resp) {
result = result.concat(resp.messages);
var nextPageToken = resp.nextPageToken;
if (nextPageToken) {
request = gapi.client.gmail.users.messages.list({
'userId': userId,
'pageToken': nextPageToken,
'q': query
});
getPageOfMessages(request, result);
} else {
callback(result);
}
});
};
var initialRequest = gapi.client.gmail.users.messages.list({
'userId': userId,
'q': query
});
getPageOfMessages(initialRequest, []);
}
You need to include the script https://apis.google.com/js/api.js somewhere in your HTML document.
That is the Google Javacsript Client library that defines the gapi variable. If you try to use gapi before it's defined, you get the error you're seeing.
See: https://developers.google.com/api-client-library/javascript/start/start-js
At the very top of the HTML file:
<script src="https://apis.google.com/js/api.js"></script>
I'm making an app that allows user to like and comment on other user post. I'm using Parse as my backend. I'm able to notified user everytime their post liked or commented. However if current user like or comment on their own post this current user still notified. How can I prevent this?
Here is the js code that I use:
Parse.Cloud.afterSave('Likes', function(request) {
// read pointer async
request.object.get("likedPost").fetch().then(function(like){
// 'post' is the commentedPost object here
var liker = like.get('createdBy');
// proceed with the rest of your code - unchanged
var query = new Parse.Query(Parse.Installation);
query.equalTo('jooveUser', liker);
Parse.Push.send({
where: query, // Set our Installation query.
data: {
alert: message = request.user.get('username') + ' liked your post',
badge: "Increment",
sound: "facebook_pop.mp3",
t : "l",
lid : request.object.id,
pid: request.object.get('likedPostId'),
lu : request.user.get('username'),
ca : request.object.createdAt,
pf : request.user.get('profilePicture')
}
}, {
success: function() {
console.log("push sent")
},
error: function(err) {
console.log("push not sent");
}
});
});
});
If I understand the context of where this code is correctly,
I recommend checking
if request.user.get("username") != Parse.CurrentUser.get("username")
Before sending out the push notification
Where is your cloud function being called from? If you're calling it from your ios code, then before you call the cloud code function, just prelude it with something like this:
if (PFUser.currentUser?.valueForKey("userName") as! String) != (parseUser.valueForKey("userName") as! String)
I'm attempting to deploy my code to Parse, and I keep getting an error stating:
Update failed with Could not load triggers. The error was Uncaught SyntaxError: Unexpected token } in main.js:454
Of the code below, line 454 that it refers to is this one:
}, function(err) {
Full code:
Parse.Cloud.define("MatchCenterTest", function(request, response) {
//defines which parse class to iterate through
var matchCenterItem = Parse.Object.extend("matchCenterItem");
var query = new Parse.Query(matchCenterItem);
var promises = [];
//setting the limit of items at 10 for now
query.limit(10);
query.find().then(function(results) {
for (i=0; i<results.length; i++) {
url = 'http://svcs.ebay.com/services/search/FindingService/v1';
//push function containing criteria for every matchCenterItem into promises array
promises.push(function() {
return Parse.Cloud.httpRequest({
url: url,
params: {
'OPERATION-NAME' : 'findItemsByKeywords',
'SERVICE-VERSION' : '1.12.0',
'SECURITY-APPNAME' : '*APP ID GOES HERE*',
'GLOBAL-ID' : 'EBAY-US',
'RESPONSE-DATA-FORMAT' : 'JSON',
'REST-PAYLOAD&sortOrder' : 'BestMatch',
'paginationInput.entriesPerPage' : '3',
'outputSelector=AspectHistogram&itemFilter(0).name=Condition&itemFilter(0).value(0)' : results[i].get('itemCondition'),
'itemFilter(1).name=MaxPrice&itemFilter(1).value' : results[i].get('maxPrice'),
'itemFilter(1).paramName=Currency&itemFilter(1).paramValue' : 'USD',
'itemFilter(2).name=MinPrice&itemFilter(2).value' : results[i].get('minPrice'),
'itemFilter(2).paramName=Currency&itemFilter(2).paramValue' : 'USD',
//'itemFilter(3).name=LocatedIn&itemFilter(3).Value' : request.params.itemLocation,
'itemFilter(3).name=ListingType&itemFilter(3).value' : 'FixedPrice',
'keywords' : results[i].get('searchTerm'),
}
});
});
}
Parse.Promise.when(promises).then(function(){
var ebayPingResults = [];
forEach(function(httpResponse) {
var httpResponse = JSON.parse(httpResponse.text);
ebayPingResults.push(httpResponse);
});
response.success(
console.log(ebayPingResults[0]); // So you can see what the response looks like for each httpRequest that was made
)
}, function(err) {
console.log('error!');
response.error('DAMN IT MAN');
});
});
});
As far as I know, that bracket belongs there. Why is this error occurring?
This piece of code looks terribly wrong:
response.success(
console.log(ebayPingResults[0]); // So you can see what the response looks like for each httpRequest that was made
)
seems like it must be
response.success(function(result) {
console.log(result);
});
In cloud code functions, the code must call either response.success() or response.error(). Each of these take an optional value that will be JSON encoded and returned to the calling code.
Your current code is calling console.log() in an entirely wrong place, and breaking the code.
Returning an anon function is also incorrect.
If you want to return the array of ping results, just use the following:
response.success(ebayPingResults);
If you want to log something, do it before your response.success() call:
console.log(ebayPingResults[0]);
response.success(ebayPingResults);
I'm working on cloud code that pings eBay, returns JSON, parses it, and stores the top two categories into an array. The parameters sent to eBay are based on what a user types into itemSearch bar the iOS app. When I attempt to send a query like "iPhone", it gives this error:
TypeError: Cannot read property 'findItemsByKeywordsResponse' of undefined
at Object.Parse.Cloud.httpRequest.success (main.js:37:15)
at Object.<anonymous> (<anonymous>:565:19) (Code: 141, Version: 1.2.18)
Here is my objective-c code:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if (sender != self.nextButton) return;
if (self.itemSearch.text.length > 0) {
[PFCloud callFunctionInBackground:#"eBayCategorySearch"
withParameters:#{#"item": self.itemSearch.text}
block:^(NSString *result, NSError *error) {
if (!error) {
NSLog(#"Successfully pinged eBay!");
}
}];
}
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
The cloud code (main.js) running on Parse:
Parse.Cloud.define("eBayCategorySearch", function(request, response) {
url = 'http://svcs.ebay.com/services/search/FindingService/v1';
Parse.Cloud.httpRequest({
url: url,
params: {
'OPERATION-NAME' : 'findItemsByKeywords',
'SERVICE-VERSION' : '1.12.0',
'SECURITY-APPNAME' : '*APP ID GOES HERE*',
'GLOBAL-ID' : 'EBAY-US',
'RESPONSE-DATA-FORMAT' : 'JSON',
'itemFilter(0).name=ListingType' : 'itemFilter(0).value=FixedPrice',
'keywords' : request.params.item,
// your other params
},
success: function (httpResponse) {
var response = JSON.parse(httpResponse.text)
// count number of times each unique primaryCategory shows up (based on categoryId), return top two (done with a for loop?)
var userCategories = {};
var data = httpResponse.data
data.findItemsByKeywordsResponse.searchResult[0].item.forEach(function(item)
{
var id = item.primaryCategory[0].categoryId;
if (userCategories[id]) userCategories[id]++;
else userCategories[id] = 1;
});
var top2 = Object.keys(userCategories).sort(function(a, b)
{return userCategories[b]-userCategories[a]; }).slice(0, 2);
console.log('Top two categories: ' + top2.join(', '));
response.success(httpResponse.data)
// if user has criteria info for one of the categories already, default to that, send to matchcenter
// if user has criteria for both categories, ask which one, default to selected categories criteria, send to matchcenter
// if user has no criteria for either category, redirect to criteriaViewController, save the criteria user inputs, send to matchcenter
// deal with success and respond to query
},
error: function (httpResponse) {
console.log('error!!!');
console.error('Request failed with response code ' + httpResponse.status);
}
});
});
The JSON usually looks like this when returned:
{
"findItemsByKeywordsResponse":[
{
"ack":[
"Success"
],
"version":[
"1.12.0"
],
"timestamp":[
"2014-03-26T18:29:40.583Z"
],
"searchResult":[
{
"#count":"100",
"item":[
{
"itemId":[
"151258132867"
],
"title":[
"Apple iPhone 4 - clean esn - Black (Verizon) Smartphone"
],
"globalId":[
"EBAY-US"
],
"primaryCategory":[
{
"categoryId":[
"9355"
],
"categoryName":[
"Cell Phones & Smartphones"
I don't think it's being returned properly, hence its inability to find "findItemsByKeywordsResponse". Is there a way I can print out the JSON being returned, to see whether I'm parsing the wrong thing?
You are parsing your response:
var response = JSON.parse(httpResponse.text)
But after that you don't use it. You work instead with httpResponse.data.
So try using your response object:
response.findItemsByKeywordsResponse.searchResult[0]......