Hi all I am trying to integrate a webservice in Titanium but when I press the button to call it my log is terminated and my app freezes. I am getting no error messages. Below is my code:
Post_array.push({
variable1:value1,
variable2:value2
variable3:value3
});
var AddJobURL="http:/NUMBERS/MytestURL";
var AddJobxhr=Titanium.Network.createHTTPClient();
AddJobxhr.onload=function(){
console.log("Response text ----------------------"+ this.responseText);
var doc= JSON.parse(this.responseText);
};
AddJobxhr.onerror=function(e){
alert(e.error);
};
AddJobxhr.open('POST', AddJobURL);
AddJobxhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
AddJobxhr.send(Post_array);
EDIT: I've realised the problem. My issue is my Post_array. What I am currently doing is pushing 4 items to an array on a button click and then pushing an additional 4 items on a second different button click and then posting this array but the array at his point is [object Object],[object Object] I think this is my issue? Any ideas how to solve?
The format of the sending data is not correct here I guess.
Below is the format in which you need to send the data:
AddJobxhr.send({
variable1: "value1",
variable2: "value2"
});
Where as Post_array is an array and not in the above format.
You should do something like:
var Post_array = {};
Post_array = $.extend(Post_array, {
"variable1": "value1",
"variable2": "value2",
"variable3": "value3"
});
Post_array = $.extend(Post_array, {
"variable4": "value4",
"variable5": "value5",
"variable6": "value6"
});
AddJobxhr.send(Post_array);
Alternatively you can do:
var Post_array = {};
// Doesn't have to be in quotes it's just the value you assign, strings are in quotes
// where as integers are not. Let us assume that value1, valu2 and value3 are the
// variable and they can hold anything;
Post_array["variable1"] = value1;
Post_array["variable2"] = value2;
Post_array["variable3"] = value3;
Post_array["variable4"] = value4;
Post_array["variable5"] = value5;
Post_array["variable6"] = value6;
AddJobxhr.send(Post_array);
Related
fun SubmitOrder(view: View) {
/* pricing of coffee */
val total = quantity * 5
val s: String = ("$$total.00")
money.text = ("Total : $s\nThank You!").toString()
//This is calling On click listener
Toast.makeText(this, "order_Submitted", Toast.LENGTH_SHORT).show()
}
In this code, I need a new line before Thank You! in money.text but I am not getting any new line I am new in android development so, am not able to point out the mistake.
Let's go thru your code line by line:
val s: String = ("$$total.00")
s is a bad variable name, as it's not descriptive at all
you don't need the (braces)
the :String here is optional. In such an obvious case i would emit it.
A $ is a sign to the kotlin compiler to include the following variable. Therefore, you can't use the $ when you mean "US-Dollar". See this post on how to escape it
While ".00" works, it's no good style. I suggest you use string formatting as described here.
can be written as val s = "\$ ${String.format("%.2f", total)}"
you should wherever possible use string resources, but thats out of the scope of this answer
money.text = ("Total : $s\nThank You!").toString()
this is correct, but unnecessary verbose:
"Total : $s\nThank You!" is already a string, so there's no need to .toString()
braces are not needed
can be written as money.text = "Total : $s\nThank You!"
I'm working on one application in which I want to fill the registration form and pass this data to API.I tried almost all solutions but not solved this issue.
I'm getting this type of data after filling the form
[
{Date of Birth of the Baby: 08/01/1997},
{Gender of the baby: male},
{Time of Birth of the Baby: 12.00 pm},
{Father's Name: Nnn},
{Mother's Name: Hbhh},
{Any Extra Details?: Bnn}
]
and I want this type of data
{
"Date of Birth of the Baby": "08/01/1997",
"Gender of the baby": "male",
"Time of Birth of the Baby": "12.00 pm",
"Father's Name": "Nnn",
"Mother's Name": "Hbhh",
"Any Extra Details?": "Bnn"
}
var fieldsData = [];
final myControllers = [];
mydynamicData() {
for (var i = 0; i <= widget.fieldData.length; i++) {
fieldsData.add({
widget.fieldData[i]['question'],
myControllers[i].text != null || myControllers[i].text != ""
? myControllers[i].text
: ""
});
}
print("fieldsData:${fieldsData}");
}
This is my method i know this issue occurred due to for loop but without for loop I'm not getting all fields data. so please help.
Import:
import 'dart:convert';
then you can use:
json.encode(fieldsData);
As you have a list of objects, it may be necessary to make a for in the list calling json.encode for each item, then encoding the result.
How do I get the first character of a string in dart flutter.
For example,a string having a value "Hello World" should return only "H".
I am fetching data from my firestore database.
My code is:
searchByName(String searchField) {
return Firestore.instance
.collection('posts')
.where('description',
isEqualTo: searchField.substring(0, 1).toUpperCase())
.getDocuments();
}
I want to get the first letter from the data that I recieve from 'description' field in above code.
You can do this by getting the first element of the String (indicated by index 0):
'${mystring[0]}'
example:
String mystring = 'Hello World';
print('${mystring[0]}');
in this case you will get as an output:
H
To get first character of string you should use method substring
Example:
word.substring(0,1);
For Perform Searching in Firebase Document Field This Will Work
void main() {
String mystring = 'Hello World';
String search = '';
for (int i=0;i<mystring.length;i++){
search += mystring[i];
print(search);
}
}
Output
H
He
Hel
Hell
Hello
Hello
Hello W
Hello Wo
Hello Wor
Hello Worl
Hello World
For me this Works.
Needed to get first n values rather than just one, and kept getting Value not in range: 10 error using substring, here's a helper function to cut a string down to the first x characters:
//* Limits given string, adds '..' if necessary
static String shortenName(String nameRaw, {int nameLimit = 10, bool addDots = false}) {
//* Limiting val should not be gt input length (.substring range issue)
final max = nameLimit < nameRaw.length ? nameLimit : nameRaw.length;
//* Get short name
final name = nameRaw.substring(0, max);
//* Return with '..' if input string was sliced
if (addDots && nameRaw.length > max) return name + '..';
return name;
}
Usage:
return Helpers.shortenName('Sausage', nameLimit: 5);
I am working on an Android application that uses a Google Spreadsheet as a database.
The application should GET, APPEND and UPDATE values in a spreadsheet, using the Sheets API v4. The first two functions are working fine but I have difficulties updating a specific row. I need to find a row that has a specific value in it's first column ("Batch ID") and update all the cells in this row.
This is how my spreadsheet looks like.
Right now I am getting the row to be modified like this:
ValueRange response = this.mySheetsService.spreadsheets().
values().get(spreadsheetId, range).execute();
List<List<Object>> values = response.getValues();
String rangeToUpdate;
Log.i(TAG, "all values in range: " + values.toString());
int i = 0;
if (values != null) {
for (List row : values) {
i += 1;
if (row.get(0).equals(selectedBatchID)) {
Log.i(TAG, "IT'S A MATCH! i= " + i);
rangeToUpdate = "A" + (i + 1) + ":E" + (i + 1); //row to be updated
}
}
}
/*once I have the row that needs to be updated, I construct my new ValueRange requestbody and
*execute a values().update(spreadsheetId, rangeToUpdate , requestbody) request.
*/
This is actually working fine but I think it's an ugly solution and I am sure there is a better one out there.
I have read the Sheets API documentation and I got familiar with notions such as batchUpdateByDataFilter, DataFilterValueRange or DeveloperMetadata and I sense that I should use these features for what I'm trying to achieve but I couldn't put them together and I couldn't find any examples.
Can someone show me or help me understand how to use these Sheets V4 features?
Thank you.
I have exactly the same issue, and it seems that so far (March 2018) Sheets v4 API does not allow to search by value, returning cell address. The solution I found somewhere here on StackOverflow is to use a formula. The formula can be created in an arbitrary sheet each time you want to find the address by value, then you erase the formula. If you do not want to delete the formula every time, you many prefer to create in a safer place, like a hidden worksheet.
Create hidden worksheet LOOKUP_SHEET (spreadsheetId is your spreadsheet ID):
POST https://sheets.googleapis.com/v4/spreadsheets/spreadsheetId:batchUpdate
{
"requests": [
{
"addSheet": {
"properties": {
"hidden": true,
"title": "LOOKUP_SHEET"
}
}
}
]
}
Create a formula in the A1 cell of the hidden worksheet that searches for "Search value" in MySheet1 sheet, and get back the row:
PUT https://sheets.googleapis.com/v4/spreadsheets/spreadsheetId/values/LOOKUP_SHEET!A1?includeValuesInResponse=true&responseValueRenderOption=UNFORMATTED_VALUE&valueInputOption=USER_ENTERED&fields=updatedData
{
"range": "LOOKUP_SHEET!A1",
"values": [
[
"=MATCH("Search value", MySheet1!A:A, 0)"
]
]
}
The response will look like this:
{
"updatedData": {
"range": "LOOKUP_SHEET!A1",
"majorDimension": "ROWS",
"values": [
[
3
]
]
}
}
By default, major dimension is ROWS. MATCH() returns relative row within column A, if no row IDs are provided then this position is effectively absolute. Or, you may want to use a more reliable call like =ROW(INDIRECT(ADDRESS(MATCH("Search value",A:A,0),1))). If the sheet has spaces in it, enclose it in single quotes. If you are searching for number, make sure you do not enclose it in quotes.
In the spreadsheets API we have the concept of developer metadata, that allow us to store information not visible to the end user that we can later on retrieve and use.
In this case the best approach is to assign the Batch ID as a metadata for a particular row. I will add the code based on the Javascript SDK.
const response = await sheets.spreadsheets.developerMetadata.search({
auth: jwtClient,
spreadsheetId,
requestBody: {
dataFilters: [
{
developerMetadataLookup: {
locationType: 'ROW',
metadataKey: 'batchId',
metadataValue: '$BATCH_ID'
}
}
]
}
});
if (response.matchedDeveloperMetadata) {
// There is a row with that id already present.
const { endIndex } = response.matchedDeveloperMetadata[0].developerMetadata.location.dimensionRange;
// Use endIndex to create the range to update the values range: `SheetName!A${endIndex}`,
await sheets.spreadsheets.values.update(
{
auth: jwtClient,
spreadsheetId,
range: `SheetName!A${endIndex}`,
valueInputOption: 'USER_ENTERED',
requestBody: {
majorDimension: 'ROWS',
values: [[]]
},
},
{}
);
} else {
// Append the value and create the metadata.
const appendResponse = await sheets.spreadsheets.values.append(
{
auth: jwtClient,
spreadsheetId,
range: 'SheetName!A1',
valueInputOption: 'USER_ENTERED',
requestBody: {
majorDimension: 'ROWS',
values: [[]]
},
},
{}
);
if (appendResponse.data.updates?.updatedRange) {
const updatedRange = appendResponse.data.updates?.updatedRange;
const [, range] = updatedRange.split('!');
const indexes = convertSheetNotation(range);
await sheets.spreadsheets.batchUpdate({ auth: jwtClient, spreadsheetId, requestBody: {
requests: [
{
createDeveloperMetadata: {
developerMetadata: {
location: {
dimensionRange: {
sheetId: 0,
startIndex: indexes[0],
endIndex: indexes[0] + 1,
dimension: "ROWS"
}
},
metadataKey: 'batchId',
metadataValue: '$BATCH_ID',
visibility: "DOCUMENT"
}
}
}
]
}});
}
}
We need to be careful of race conditions as we may end up with duplicated rows, let me know if that helps :)
I had the same requirement.
First:
Create a function that gets the index of targeted object from the sheet, like:
private int getRowIndex(TheObject obj, ValueRange response) {
List<List<Object>> values = response.getValues();
int rowIndex = -1;
int i = 0;
if (values != null) {
for (List row : values) {
i += 1;
if (row.get(1).equals(obj.getBatchId())) {
System.out.println("There is a match! i= " + i);
rowIndex = i;
}
}
}
return rowIndex;
}
Second:
Create the update method by passing the targeted object having your desired value "batch id" and others new values for the rest of fields.
public void updateObject(Object obj) throws IOException, GeneralSecurityException {
sheetsService = getSheetsService();
ValueRange response = sheetsService.spreadsheets().
values().get(SPREADSHEET_ID, "Sheet1").execute();
int rowIndex = this.getRowIndex(obj, response);
if (rowIndex != -1) {
List<ValueRange> oList = new ArrayList<>();
oList.add(new ValueRange().setRange("B" + rowIndex).setValues(Arrays.asList(
Arrays.<Object>asList(obj.getSomeProprty()))));
oList.add(new ValueRange().setRange("C" + rowIndex).setValues(Arrays.asList(
Arrays.<Object>asList(obj.getOtherProprty()))));
//... same for others properties of obj
BatchUpdateValuesRequest body = new BatchUpdateValuesRequest().setValueInputOption("USER_ENTERED").setData(oList);
BatchUpdateValuesResponse batchResponse;
batchResponse sheetsService.spreadsheets().values().batchUpdate(SPREADSHEET_ID, body).execute();
} else {
System.out.println("the obj dont exist in the sheet!");
}
}
Finally:
In your app you have to pass the tageted object to the update method:
TheObject obj = new Object();
obj.setBatchId = "some value";
Fill the obj with others values if you want.
Then call the method:
objectChanger.updateObject(obj);
All you need to do is to create a new array of strings from an array of arrays - so you can run the indexOf() method on this new array.
Since we know the method values.get returns array of the arrays such as
[
[""],
[""],
...
]
my approach was to a bit flattened this structure.
const data = await googleSheetsInstance.spreadsheets.values.get({
//here u have to insert auth, spreadsheetId and range
});
//here you will get that array of arrays
const allData: any[] = data.data.values;
//Now you have to find an index in the subarray of Primary Key (such as
//email or anything like that
const flattenedData = allData.map((someArray: any[]) => {
return someArray[2]; //My primary key is on the index 2 in the email
Array
});
So what you will get is a normal array of strings with primary keys so now you can easily call the indexOf() on the flattened array.
const index:number = flattenedData.indexOf("someuniquestring);
console.log(index);
And the index value will tell you the row. Do not forget spreadsheets start from 1 and indexes in Javascript start from 0.
does someone use gameNetwork provided by Google Play? Im having a little problem with it, im trying to fetch personal best score and its not working well.
Here is the code that i use
function loadScoreCallback(event)
oldScore = event.data[5].formattedValue
end
gameNetwork.request( "loadScores",
{
leaderboard =
{
category = "thecategory id",
playerScope = "Global", -- Global, FriendsOnly
timeScope = "AllTime", -- AllTime, Week, Today
range = {1,5},
playerCentered = true,
},
listener = loadScoreCallback
})
I also tried something like
function loadScoreCallback(event)
oldScore = event.data
end
gameNetwork.request( "loadScores",
{
leaderboard =
{
playerID = playerName,
category = "CgkIptXi1qgCEAIQAw",
playerScope = "Global", -- Global, FriendsOnly
timeScope = "AllTime", -- AllTime, Week, Today
playerCentered = true,
},
listener = loadScoreCallback
})
Also didnt work :/
I had some trouble figuring this out, but I found a solution that works for me.
this is the listener that is called when the user submits a score.
local function onGameNetworkRequestResult( event )
if event.type == "setHighScore" then
local function tempScoresFct(event)
if event.data then
local playerRank = event.data[1].rank
local currentValue = event.data[1].value
if lb.tempScore <= event.data[1].value then
native.showAlert("Score submitted", "You score is lower or equal than your current score in the leaderboard("..currentValue.."), nothing changed. Your global, all time rank is:\n" .. playerRank .. "\nTo see how you are doing among your friends and in other time scales, click the button \"show leaderboard\".", {"Ok"})
else
native.showAlert("Score submitted", "Your score was successfully uploaded to the leaderboard. Your global, all time rank is:\n" .. playerRank .. "\nTo see how you are doing among your friends and in other time scales, click the button \"show leaderboard\".", {"Ok"})
end
end
end
gameNetwork.request( "loadScores",
{
leaderboard =
{
category = event.data.category,
playerScope = "Global", -- Global, FriendsOnly
timeScope = "AllTime", -- AllTime, Week, Today
range = {1,1}, --Just get one player
playerCentered = true, -- and this player is the player that is logged in
},
listener = tempScoresFct
})
end
end
and this ist the function that submits the score:
function lb.submitScoreFct(event)
if event.phase == "ended" then
if gameNetwork.request("isConnected") then
--show leaderboards
print("submitting score")
local myCategory
local categoryName
if event.target.category == 1 then
myCategory = "ategoryID" --palo alto
categoryName = "Palo Alto"
elseif event.target.category == 2 then
myCategory = "ategoryID" --groningen
categoryName = "Groningen"
elseif event.target.category == 3 then
myCategory = "ategoryID" --sp2
categoryName = "SP2"
end
--local score = mRand(100,1000)
local score = event.target.score
lb.tempScore = score -- i use this to verify if the uploaded score was higher or lower then the value that is already there
print("Added " .. score .. " to " .. categoryName)
gameNetwork.request( "setHighScore",
{
localPlayerScore = { category=myCategory, value=tonumber(score) },
listener = lb.onGameNetworkRequestResult
})
end
else
print("user needs to log in")
-- Tries to login the user, if there is a problem then it will try to resolve it. eg. Show the log in screen.
gameNetwork.request("login",
{
listener = loginListener,
userInitiated = true -- if that is false, than this process is silent ie dont pop up a log in if the user is not logged in
})
end
return true
end
Oh and one thing I figured out, is that this listener functions are fragile. If there is one error inside, they quit and sometimes dont give any error.
For example if you try to print(event.data.rank) (instedt of print(event.data[1].rank)) there is no error but the function ends at this point and the rest of the function is not executed...
Well so i found a better idea, since not everyone is online all the time i made my own saving system, and it fetches high score from there. But i still dont know why it doesnt work, well at least i solved it with this.