Return value from 'Future' function - flutter

I hope you can help me with getting a return value out of a future function.
I created a local MariaDB and connect to it with the mysql1 package. The next step is to get a value whenever a table is empty or not (indicates as 0 or 1). I archive that behavior with the following SQL query SELECT EXISTS (SELECT 1 FROM table);
Function to create a db connection.
//creates connection to local database. (used in .this((conn){}) function)
Future<MySqlConnection> getConnection() async {
var settings = ConnectionSettings(
host: host!,
port: port!,
user: user,
password: password,
db: db,
);
return await MySqlConnection.connect(settings);
}
My Function that should return 0 or 1, let me explan the code block down below.
getConnection() create database connection
trigger .then() to work with the output as conn
execute SQL query
format SQL query to just 0 or 1
Missing: should return the value when checkIfTableIsEmpty() is called
//should return 0 or 1 depending if table is empty or not.
checkIfTableIsEmpty(String table) async {
//holds the sql query that should get executed.
String sql = 'SELECT EXISTS (SELECT 1 FROM $table);';
//this should get returned after annitialised.
String? globalNumber;
//!!! creates the value 0 or 1 !!!
await getConnection().then( // (1)
(conn) async { // (2)
//output: result = (Fields: {EXISTS (SELECT 1 FROM master_key): 1})
Results result = await conn.query(sql); //(3)
String? number;
for (var row in result) {. // (4) <---- format output to just 0 or 1
number = '${row[0]}';
}
globalNumber = number;
print('$globalNumber'); // <---- output is 1
return globalNumber;
});
// (5) globalNumber should get printed
print('$globalNumber'); // <---- output null, this should be 1
}
Function that is currently returning null but should get value of globalNumber var.
//call the function and print result.
void testFunction() async {
print(checkIfTableIsEmpty('master_key'));
}

Hello i found the solution for my problem. I had to await on the result and delete the .then() function to avoid having callbacks. (See the comment of #Almis).
Thanks #Almis for the code improvement.
This is my final function that return 0 or 1.
checkIfTableIsEmpty(String table) async {
String sql = 'SELECT EXISTS (SELECT 1 FROM $table);';
String? globalNumber;
var conn = await getConnection();
Results result = await conn.query(sql);
for (var row in result) {
globalNumber = '${row[0]}';
}
return globalNumber;
}
void testFunction() async {
var x = await checkIfTableIsEmpty('master_key');
print(x);
}

Related

How do I print my inserted values in my console? (Flutter | sqflite)

I am currently successfully able to insert values into the system, however, I want to be able to display the inserted values in my console.
How do I print the inserted values in my console? I tried doing so and I was only able to get the "id" of the inserted value. I'm not sure how to print the rest of the values in the table.
Here's my insert code:
// Insert Operation: Insert a Note object to database
Future<int> insertNote(Note note) async {
//getting db reference
Database db = await database;
//running the insert command
//our data from note is converted to map object
var result = await db.insert(noteTable, note.toMap());
if (kDebugMode) {
print('Note data inserted successfully: $result');
}
return result;
}
Here's the code I used to convert the Note object into a Map object
// Convert a Note object into a Map object
Map<String, dynamic> toMap() {
var map = <String,dynamic>{};
if (id != null) {
map['id'] = _id;
}
map['title'] = _title;
map['description'] = _description;
map['priority'] = _priority;
map['color'] = _color;
map['date'] = _date;
return map;
}
This is the result on my console:
When you insert row in database you will only get row id in return.
So if you want to print recent data then you have to make a query to your database with id or you can also print all the data available.
For table
db.query("table_name);
or
db.rawQuery('SELECT * FROM "table"');
For specific id
db.query("table_name",where: '$rowId = ?', whereArgs: [id]);
or
db.rawQuery('SELECT * FROM "table" WHERE $rowId = $id');
For more info check : https://pub.dev/packages/sqflite

My async metho didn't go after "for" iteration

My code like this:
Future<List<ListClass>> getIndexList() async {
return Future.delayed(delayTime).then((_) async {
//initialize
List<ListClass> resultListItems = new List<ListClass>();
await listCollection.get().then((value) async {
var v = value.data;
for (var data in v) {
String userId = data['userId'];
String authorName=await UserTable().getUserNameById(userId);
print("createUserName=" + authorName);
resultListItems.add(
ListClass(header, content, userId, wordCount, authorName));
}
print("resultListItems.length="+resultListItems.length.toString());
return resultListItems;
});
return resultListItems;
});
}
When I debug,it shows that this method return null,and after the for,the print("resultListItems"); doesn't run too. How can I fix this?Thanks!!
I have found the problem,the for clause doesn't run completely.One of my data in database is null,so it runs with bug.Sorry for my fault

how to transform a Future<dynamic> to string in dart:flutter

I’m using some sqflite to do a query on a database, and extract a specific name of a table, for example: I have 3 names, Roberto, Ricardo and Andres, and I want to obtain only the name of Roberto, so this is what im doing:
loginLogic() async {
var X = 'Roberto';
final db = await database;
List<Map> result = await db.rawQuery('SELECT * FROM Usuario WHERE username=?', [X]);
So now, I want to compare this result with another one to do an "if" function, just like this:
if(result==X){
return 1;
} else {
return 0;
}
But this is what flutter says:
List<Map<dynamic, dynamic>> result
Equality operator '==' invocation with references of unrelated
And the Debug console:
type 'Future<dynamic>' is not a subtype of type 'int'
So I need a way to compare the value that results from the list of users with the string with the variable I declarated 'X'.
Try using the reference of this problem
This is what I’ve tried:
loginLogicpar() async {
var X = 'Giova';
final db = await database;
final result = await db.rawQuery('SELECT * FROM Usuario WHERE username=?', [X]);
return result;
}
loginLogic() async {
var X = 'Giova';
final user = await loginLogicpar();
if(user==X){
return 1;
}
return 0;
}
And returns the exact same result: type 'Future' is not a subtype of type 'int'
Added the code so you can replicate it, just be sure you have sqflite on your depenencies.
It was a hell of a road, but i made it with the help of you all, but the final piece was #mutantkeyboard, what i was getting was a list of the different elements from the table of Sqflite, but after converting it with a variable and the .first function i get to transform it to another variables! here's what i made:
loginLogic() async {
final db = await database;
var table = await db.rawQuery("SELECT MAX(id)+1 as id FROM Usuario");
int id = table.last["id"];
for(var i=1; i<id; i++){
var result = await db.rawQuery('SELECT username FROM Usuario WHERE id=?', [i]);
String Y = result.first["username"];
if(Y=='Roberto'){
return 1;
}
}
return 0;
}
if you want to compare it with another variable outside, for example, an auth for a local-login (that's what i was doing, just for educational purpose, i'll NEVER suggest you to put your usernames and passwords inside your local software) and compare the textfield.text with the table, then you can modify the code to something like this:
loginLogic(String field) async {
final db = await database;
var table = await db.rawQuery("SELECT MAX(id)+1 as id FROM Usuario");
int id = table.last["id"];
for(var i=1; i<id; i++){
var result = await db.rawQuery('SELECT username FROM Usuario WHERE id=?', [i]);
String Y = result.first["username"];
if(Y==field){
return 1;
}
}
return 0;
}

CosmosDB Paging Return Value

I am trying to return paging results the request from CosmosDB. I saw this example from here but I am not sure what to do with the response variable.
// Fetch query results 10 at a time.
var queryable = client.CreateDocumentQuery<Book>(collectionLink, new FeedOptions { MaxItemCount = 10 });
while (queryable.HasResults)
{
FeedResponse<Book> response = await queryable.ExecuteNext<Book>();
}
Am I suppose to return it directly? Or do I have to do something further with the response variable? I tried to return the response variable directly and it's not working. Here's my code:
public async Task<IEnumerable<T>> RunQueryAsync(string queryString)
{
var feedOptions = new FeedOptions { MaxItemCount = 3 };
IQueryable<T> filter = _client.CreateDocumentQuery<T>(_collectionUri, queryString, feedOptions);
IDocumentQuery<T> query = filter.AsDocumentQuery();
var response = new FeedResponse<T>();
while (query.HasMoreResults)
{
response = await query.ExecuteNextAsync<T>();
}
return response;
}
Update:
After reading #Evandro Paula's answer, I followed the URL and changed my implementation to below. But it is still giving me 500 status code:
public async Task<IEnumerable<T>> RunQueryAsync(string queryString)
{
var feedOptions = new FeedOptions { MaxItemCount = 1 };
IQueryable<T> filter = _client.CreateDocumentQuery<T>(_collectionUri, queryString, feedOptions);
IDocumentQuery<T> query = filter.AsDocumentQuery();
List<T> results = new List<T>();
while (query.HasMoreResults)
{
foreach (T t in await query.ExecuteNextAsync())
{
results.Add(t);
}
}
return results;
}
And here's the exception message:
Cross partition query is required but disabled. Please set
x-ms-documentdb-query-enablecrosspartition to true, specify
x-ms-documentdb-partitionkey, or revise your query to avoid this
exception., Windows/10.0.17134 documentdb-netcore-sdk/1.9.1
Update 2:
I added the EnableCrossPartitionQuery to true and I am able to get the response from CosmosDB. But I am not able to get the 1 item that I defined. Instead, I got 11 items.
Find below a simple example on how to use the CosmosDB/SQL paged query:
private static async Task Query()
{
Uri uri = new Uri("https://{CosmosDB/SQL Account Name}.documents.azure.com:443/");
DocumentClient documentClient = new DocumentClient(uri, "{CosmosDB/SQL Account Key}");
int currentPageNumber = 1;
int documentNumber = 1;
IDocumentQuery<Book> query = documentClient.CreateDocumentQuery<Book>("dbs/{CosmoDB/SQL Database Name}/colls/{CosmoDB/SQL Collection Name}", new FeedOptions { MaxItemCount = 10 }).AsDocumentQuery();
while (query.HasMoreResults)
{
Console.WriteLine($"----- PAGE {currentPageNumber} -----");
foreach (Book book in await query.ExecuteNextAsync())
{
Console.WriteLine($"[{documentNumber}] {book.Id}");
documentNumber++;
}
currentPageNumber++;
}
}
Per exception described in your question Cross partition query is required but disabled, update the feed options as follows:
var feedOptions = new FeedOptions { MaxItemCount = 1, EnableCrossPartitionQuery = true};
Find a more comprehensive example at https://github.com/Azure/azure-documentdb-dotnet/blob/d17c0ca5be739a359d105cf4112443f65ca2cb72/samples/code-samples/Queries/Program.cs#L554-L576.
you are not specifying any where criteria for your specific item...so you are getting all results..try specifying criteria for the item (id , name etc) you are looking for. And keep in mind cross partition queries consume much more RUs n time, you can revisit architecture of your data model..Ideally always do queries with in same partition

Resolving a Promise in Protractor

Strange issue I don't understand yet when trying to resolve (fulfill) my promise in Protractor.
Something is very wrong with the line deferred.fulfill(rowData);, as it's NOT returning the row data as I would expect.
In other words, rowData.count() in the lower function is fine, but when returned row.count() is failing.
this.gridFunction = function (summaryData){
var rowData = getGridRowByText(gridRows, name, text);
rowData.then(function (row) {
// ** THROWS ERROR ** TypeError: row.count is not a function
expect(row.count()).toEqual(3);
row.map(function (cell) {
// iterate cell contents, compare with "summaryData"
});
});
}
function getGridRowByText(gridRows, grid, text) {
var deferred = protractor.promise.defer();
var parentId = getParId();
parentId.getAttribute("id").then(function (parentId) {
// i.e. jquery $('.grid-wrapper.fluid-wrapper #rowId_21')
var sel = '.grid-wrapper.fluid-wrapper #' + parentId;
var rowData = element(by.css(sel)).all(by.repeater('column in vm.sourceData.columns'));
// EXPECT SUCCESSFULL !!!
expect(rowData.count()).toEqual(19);
deferred.fulfill(rowData);
});
return deferred.promise;
};
Main question: am I NOT properly returning the fulfilled promise with the rowData object ?
* UPDATE *
My final solution :
It doesn't actually solve my original problem of working with the Protractor Promise, but rather just a redesign of the logic.
this.gridFunction = function (targetRowText){
var result = gridRows.all(by.cssContainingText('span', targetRowText)).first();
var parentId = result.all(by.xpath("./ancestor::div[starts-with(#id, 'rowId')]"));
parentId.getAttribute("id").then(function (parentId) {
console.log(' (ROW-ID: ', parentId);
// further iterations here...
}
}
thank you,
Bob
You don't actually need a "deferred" object here. Just return the promise from the function:
function getGridRowByText(gridRows, grid, text) {
var parentId = getParId();
return parentId.getAttribute("id").then(function (parentId) {
var sel = '.grid-wrapper.fluid-wrapper #' + parentId;
return element(by.css(sel)).all(by.repeater('column in vm.sourceData.columns'));
});
};
Usage:
var rowData = getGridRowByText(gridRows, name, text);
expect(rowData.count()).toEqual(3);
Or, if further processing needed in the getgridRowByText() function:
function getGridRowByText(gridRows, grid, text) {
var parentId = getParId();
return parentId.getAttribute("id").then(function (parentId) {
var sel = '.grid-wrapper.fluid-wrapper #' + parentId;
var rowData = element(by.css(sel)).all(by.repeater('column in vm.sourceData.columns'));
// further processing here
expect(rowData.count()).toEqual(19);
return rowData;
});
};