I am trying to use BLOC inside my login page.. but I always get paused on exception that say Exception has occurred. _TypeError (type 'List<LoginRespon>' is not a subtype of type 'String') here is the code
isClick == true
? StreamBuilder(
initialData: bloc.inData(_name.text,_password.text),
stream: bloc.loginData,
builder: (context,
AsyncSnapshot snapshot) {
if (snapshot.hasData) {
print(snapshot.data);
print('ppp ');
return Text('ok');
} else
return Text(snapshot.error
.toString());
})
: RaisedButton(
child: Text('Login'),
onPressed: () {
setState(() {
isClick = true;
});
},
),
and here is bloc file
class MyBLoc{
final _repository = Repository();
final _loginController = StreamController<String>();
Stream<String> get loginData => _loginController.stream;
final _name = BehaviorSubject<String>();
final _password = BehaviorSubject<String>();
saving(){
_repository.saving(_name.value,_password.value);
}
inData(String name, String password) async {
// I get paused on exception inside this method...
String result = await _repository.saving(name, password);
_loginController.sink.add(result);
}
dispose(){
_input.close();
_loginController.close();
_password.close();
}
}
final bloc = MyBLoc();
here is my repository file
class Repository{
static final userAPIProvider = UserProvider();
Future saving(String name, String password) => userAPIProvider.saving(name, password);
}
and here is my provider
class UserProvider {
final _url = '...';
Future<List<LoginRespon>> saving(String name, String password) async {
List<LoginRespon> datalogin = [];
try {
bool trustSelfSigned = true;
HttpClient httpClient = new HttpClient()
..badCertificateCallback =
((X509Certificate cert, String host, int port) => trustSelfSigned);
IOClient client = new IOClient(httpClient);
print("cek");
final response = await client.post(_url,
headers: {
HttpHeaders.contentTypeHeader: 'application/json',
},
body: json.encode({
"name": name,
"pas": password,
}));
Map<String, dynamic> responseJson = json.decode(response.body);
if (responseJson["status"] == "200") {
datalogin.add(LoginRespon(
status: responseJson['status'],
data: Data(
name: responseJson['data']['name'],
status: responseJson['data']['status'])));
return datalogin;
} else {
print("ppp");
}
} on Exception {
rethrow;
}
return datalogin;
}}
and for my LoginRespon model is available here how to create a list from json string in flutter
Paused on exception happens inside bloc file in inData method is there a way to resolve this problem Exception has occurred. _TypeError (type 'List<LoginRespon>' is not a subtype of type 'String')
In MyBloc, the returned value is supposed to be String
String result = await _repository.saving(name, password);
But it's not the case with the following line in the repository
Future saving(String name, String password) => userAPIProvider.saving(name, password);
It's returning List<LoginRespon>
Related
I have an xlsx excel table and I need to convert it into a List<Object> and take just the following columns: D, F, H, J, L. I'm trying everything but nothing works.
I'm using the following plugin to do it:
file_picker
excel
Does anyone know how can I convert it?
Table
Here is my example code:
import 'package:adminpanelweb/models/import_users.dart';
import 'package:excel/excel.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
Future importUsers(BuildContext context, String palaceId) async {
FilePickerResult? pickedFile = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['xlsx'],
allowMultiple: false,
);
if (pickedFile != null) {
var bytes = pickedFile.files.single.bytes;
var excel = Excel.decodeBytes(bytes!);
List<ImportUsers> users = [];
List<String> stringList = [];
for (var table in excel.tables.keys) {
for (var rows in excel.tables[table]!.rows) {
// print(
// '${rows.toString().isNotEmpty ? rows.map((e) => e?.value).toList() : ''}',
// );
stringList.add(
'${rows.toString().isNotEmpty ? rows.map((e) => e?.value).toList() : ''}');
}
}
final regExp = RegExp(r'(?:\[)?(\[[^\]]*?\](?:,?))(?:\])?');
final input = stringList.toString();
final result = regExp
.allMatches(input)
.map((m) => m.group(1))
.map((String? item) => item?.replaceAll(RegExp(r'[\[\]]'), ''))
.map((m) => [m])
.toList();
for (var items in result) {
users = items.map((e) {
return {
"field1": e?[0],
"WEB": e?[1],
"R": e?[2],
"Denominazione": e?[3],
"Data Uscita": e?[4],
"Codice Fiscale": e?[5],
"Partita IVA": e?[6],
"Username": e?[7],
"field9": e?[8],
"Password": e?[9],
"Profilo": e?[10],
"Email": e?[11],
};
}).toList() as List<ImportUsers>;
print(items);
}
// print('sadasdasdasdsad ${users.length}');
}
}
After some hours I solved as it:
Future importUsers(BuildContext context, String palaceId) async {
FilePickerResult? pickedFile = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['xlsx'],
allowMultiple: false,
);
if (pickedFile != null) {
List<User> xlsxToList = [];
var bytes = pickedFile.files.single.bytes;
var excel = Excel.decodeBytes(bytes!);
for (var table in excel.tables.keys) {
for (var row in excel.tables[table]!.rows) {
xlsxToList.add(
User(
userEmail: row[11]?.value.toString(),
userUsername: row[7]?.value.toString(),
userName: row[3]?.value.toString(),
userCf: row[5]?.value.toString(),
userPassword: row[9]?.value.toString(),
),
);
}
}
xlsxToList.removeAt(0);
print('__________ ${userToJson(xlsxToList)}');
}
}
Here is the RESTful API response json:
{
"success": true,
"data": {
"loginname": "mrdulin",
"avatar_url": "https://avatars1.githubusercontent.com/u/1147375?v=4&s=120",
"githubUsername": "mrdulin",
"create_at": "2012-09-09T05:26:58.319Z",
"score": 15835,
"recent_topics": [
{
"id": "5c6d11d033b0b629ac8434ef",
"author": {
"loginname": "mrdulin",
"avatar_url": "https://avatars1.githubusercontent.com/u/1147375?v=4&s=120"
},
"title": "grpc and Node.js",
"last_reply_at": "2019-05-11T04:22:18.616Z"
}
],
"recent_replies": []
}
}
UserServiceImpl.ts:
export class UserServiceImpl implements IUserServiceServer {
public async getUserByLoginname(call: ServerUnaryCall<GetUserByLoginnameRequest>, callback: sendUnaryData<GetUserByLoginnameResponse>) {
const loginname = call.request.getLoginname();
const url = `${config.CNODE_API_URL}/user/${loginname}`;
try {
const res = await axios.get(url);
const data = res.data.data;
// map API response js plain object to GetUserByLoginnameResponse
const grcpResponse = new GetUserByLoginnameResponse();
grcpResponse.setSuccess(res.data.success);
const user = new UserDetail();
user.setAvatarUrl(data.avatar_url);
user.setLoginname(data.loginname);
user.setGithubusername(data.githubUsername);
user.setCreateAt(data.create_at);
user.setScore(data.score);
const recentReplies = data.recent_replies.map((po) => {
const reply = new RecentReply();
reply.setId(po.id);
reply.setTitle(po.title);
const lastReplyAt = new google_protobuf_timestamp_pb.Timestamp();
lastReplyAt.fromDate(new Date(po.last_reply_at));
reply.setLastReplyAt(lastReplyAt);
const author = new UserBase();
author.setLoginname(po.author.loginname);
author.setAvatarUrl(po.author.avatar_url);
reply.setAuthor(author);
return reply;
});
const recentTopics = data.recent_topics.map((po) => {
const topic = new TopicBase();
topic.setId(po.id);
topic.setTitle(po.title);
topic.setLastReplyAt(po.last_reply_at);
const author = new UserBase();
author.setLoginname(po.author.loginname);
author.setAvatarUrl(po.author.avatar_url);
topic.setAuthor(author);
return topic;
});
user.setRecentRepliesList(recentReplies);
user.setRecentTopicsList(recentTopics);
grcpResponse.setData(user);
callback(null, grcpResponse);
} catch (error) {
console.error(error);
const metadata = new Metadata();
metadata.set('url', url);
const ErrGetUserByLoginname: ServiceError = {
code: status.INTERNAL,
name: 'getUserByLoginnameError',
message: 'call CNode API failed',
metadata,
};
callback(ErrGetUserByLoginname, null);
}
}
}
As you can see, I have to map the plain javascript object(the API response) to GetUserByLoginnameResponse class manually. This is cumbersome and inefficient.
I am using static codegen, so the GetUserByLoginnameResponse class is generated based on IDL defined in the .proto files.
user.service.proto:
service UserService {
rpc GetUserByLoginname(GetUserByLoginnameRequest)
returns (GetUserByLoginnameResponse);
}
message GetUserByLoginnameRequest { string loginname = 1; }
message GetUserByLoginnameResponse {
UserDetail data = 1;
bool success = 2;
}
message UserDetail {
string loginname = 1;
string avatar_url = 2;
string githubUsername = 3;
string create_at = 4;
int32 score = 5;
repeated share.TopicBase recent_topics = 6;
repeated reply.RecentReply recent_replies = 7;
}
I am using a login dialog with below code. How do I know if user is authenticated or not ?
namespace Sample.Dialogs
{
public class LoginDialog : ComponentDialog
{
private readonly BotStateService _botStateService;
public LoginDialog(string dialogId, BotStateService botStateService) : base(dialogId)
{
_botStateService = botStateService ?? throw new
System.ArgumentNullException(nameof(botStateService));
InitializeWaterfallDialog();
}
private void InitializeWaterfallDialog()
{
AddDialog(new OAuthPrompt(
nameof(OAuthPrompt),
new OAuthPromptSettings
{
ConnectionName = "",
Text = "Please login",
Title = "Login",
Timeout = 300000, // User has 5 minutes to login
}));
AddDialog(new TextPrompt(nameof(TextPrompt)));
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
{
PromptStepAsync,
LoginStepAsync
}));
InitialDialogId = nameof(WaterfallDialog); //InitialDialogId = $"
{nameof(LoginDialog)}.mainFlow";
}
private async Task<DialogTurnResult> PromptStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var tokenResponse = (TokenResponse)stepContext.Result;
if (tokenResponse != null)
{
return await stepContext.EndDialogAsync();
}
else
{
return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null , cancellationToken);
}
}
private async Task<DialogTurnResult> LoginStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var tokenResponse = (TokenResponse)stepContext.Result;
// if token exists
if (tokenResponse != null)
{
// welcome user
await stepContext.Context.SendActivityAsync(MessageFactory.Text("You are now logged
in."),cancellationToken);
// Display the name
await OAuthHelpers.GetUserDetail(stepContext.Context, tokenResponse);
return await stepContext.CancelAllDialogsAsync();
}
await stepContext.Context.SendActivityAsync(MessageFactory.Text("Login was not successful
please try again."), cancellationToken);
return await stepContext.EndDialogAsync();
}
}
}
Now, even after successful login user have to type something to know if they logged in or not. However, we want once the login is (Azure AD) successful message should push to user from bot saying that your name is this and you have successfully logged in.
How do we achieve this. ?
Thanks,
I've been trying to convert the functions in this https://blog.jeremylikness.com/build-a-serverless-link-shortener-with-analytics-faster-than-finishing-your-latte-8c094bb1df2c to a WebAPI equivalent. This is my webapi call:
[HttpPost]
public async Task<IActionResult> PostAsync([FromBody] ShortRequest shortRequest)
{
_logger.LogInformation($"ShrinkUrl api called with req: {shortRequest}");
if(!Request.IsHttps && !Request.Host.Host.Contains("localhost"))
return StatusCode(StatusCodes.Status400BadRequest);
if (string.IsNullOrEmpty(shortRequest.Input))
return StatusCode(StatusCodes.Status404NotFound);
try
{
var result = new List<ShortResponse>();
var analytics = new Analytics();
// determine whether or not to process analytics tags
bool tagMediums = analytics.Validate(shortRequest);
var campaign = string.IsNullOrWhiteSpace(shortRequest.Campaign) ? DefaultCampaign : shortRequest.Campaign;
var url = shortRequest.Input.Trim();
var utm = analytics.TagUtm(shortRequest);
var wt = analytics.TagWt(shortRequest);
_logger.LogInformation($"URL: {url} Tag UTM? {utm} Tag WebTrends? {wt}");
// get host for building short URL
var host = Request.Scheme + "://" + Request.Host;
await _tableOut.CreateIfNotExistsAsync();
if (_keyTable == null)
{
_logger.LogInformation($"Keytable is null, creating initial partition key of 1");
_keyTable = new NextId
{
PartitionKey = "1",
RowKey = "KEY",
Id = 1024
};
var keyAdd = TableOperation.Insert(_keyTable);
await _tableOut.ExecuteAsync(keyAdd);
}
// strategy for getting a new code
string getCode() => Utility.Encode(_keyTable.Id++);
// strategy for logging
void logFn(string msg) => _logger.LogInformation(msg);
// strategy to save the key
async Task saveKeyAsync()
{
var operation = TableOperation.Replace(_keyTable);
await _tableOut.ExecuteAsync(operation);
}
// strategy to insert the new short url entry
async Task saveEntryAsync(TableEntity entry)
{
var operation = TableOperation.Insert(entry);
await _tableOut.ExecuteAsync(operation);
}
// strategy to create a new URL and track the dependencies
async Task saveWithTelemetryAsync(TableEntity entry)
{
await TrackDependencyAsync(
"AzureTableStorageInsert",
"Insert",
async () => await saveEntryAsync(entry),
() => true);
await TrackDependencyAsync(
"AzureTableStorageUpdate",
"Update",
async () => await saveKeyAsync(),
() => true);
}
if (tagMediums)
{
// this will result in multiple entries depending on the number of
// mediums passed in
result.AddRange(await analytics.BuildAsync(
shortRequest,
Source,
host,
getCode,
saveWithTelemetryAsync,
logFn,
HttpUtility.ParseQueryString));
}
else
{
// no tagging, just pass-through the URL
result.Add(await Utility.SaveUrlAsync(
url,
null,
host,
getCode,
logFn,
saveWithTelemetryAsync));
}
_logger.LogInformation($"Done.");
//return req.CreateResponse(HttpStatusCode.OK, result);
}
catch (Exception ex)
{
_logger.LogError("An unexpected error was encountered.", ex);
//return req.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
}
return null;
}
And this is the function params:
[FunctionName("ShortenUrl")]
public static async Task<HttpResponseMessage>([HttpTrigger(AuthorizationLevel.Function, "post")],HttpRequestMessage req,
[Table(Utility.TABLE, "1", Utility.KEY, Take = 1)]NextId keyTable,
[Table(Utility.TABLE)]CloudTable, TraceWriter log)
The azure function takes care of ensuring that the keyTable contains the next Id in the counter but I cannot figure out how to do the same in the webapi call.
Any ideas?
I have this function in my implementation.js file:
getForecast({ context, entities } ) {
const location = firstEntityValue(entities, 'location');
if (location) {
/* global fetch */
return fetch(`https://api.apixu.com/v1/forecast.json?key=someKey&q=${location}`)
.then(response => response.json())
.then((responseJSON) => {
context.forecast = `whatever`;
delete (context.missingLocation : boolean);
return context;
});
}
delete (context.forecast);
return context;
}
And this is my unit test for this function:
it('should return the expected context when location is valid', () => {
const firstEntityValueMock = sinon.mock(imp);
console.log(firstEntityValueMock);
firstEntityValueMock.expects('firstEntityValue')
.once()
.withArgs(entities, 'location')
.returns('Paris');
const scope = nock('https://api.apixu.com')
.get(/.*/)
.reply(200, fetchResult);
const currentResult = `whatever`;
return imp.actions.getForecast({ context, entities })
.then((resultContext) => {
const res1 = _.lowerCase(resultContext.forecast);
const res2 = _.lowerCase(currentResult);
expect(res1).to.eql(res2);
expect(resultContext.missingLocation).to.be.undefined;
firstEntityValueMock.verify();
});
});
When I run my test, i get this error : ExpectationError: Expected firstEntityValue once (never called)
imp : const imp = require('../build/implementation.js');
I'm exporting my functions in implementation.js, I tried to replace the mock.verify() positioning, I tried some other syntaxes, I always get this error...