code for api_addEvent.dart
class ApiAddEventToCalender {
Future<ApiResponseData> addEventToCalender(
String token,
String date,
String time,
String previousEventDocID,
int eventDateEpocMilisecond) async {
ApiResponseData apiResponseData =
ApiResponseData(responseCode: "27", responseMsg: "Unknown Error");
var url = '${Constants.apiEndPoint}/addEventToCalender';
if (date.length < 1) {
ApiResponseData apiResponseData =
ApiResponseData(responseCode: "17", responseMsg: "Invalid date.");
return apiResponseData;
}
if (eventTitle.text.length < 1) {
ApiResponseData apiResponseData = ApiResponseData(
responseCode: "17", responseMsg: "Event title is required.");
return apiResponseData;
}
if (eventString.text.length < 1) {
ApiResponseData apiResponseData = ApiResponseData(
responseCode: "17", responseMsg: "Event description is required.");
return apiResponseData;
}
Map data = {
"Token": token,
"API": "AddEventToCalender",
"Data": {
"tokenType": "jwt",
"date": date,
"title": eventTitle.text,
"event": eventString.text,
"time": time,
"eventDateEpocMilisecond": eventDateEpocMilisecond
}
};
if (previousEventDocID.length > 10) {
data = {
"Token": token,
"API": "AddEventToCalender",
"Data": {
"tokenType": "jwt",
"date": date,
"title": eventTitle.text,
"event": eventString.text,
"time": time,
"eventDateEpocMilisecond": eventDateEpocMilisecond,
"previousEventDocID": previousEventDocID,
}
};
}
//encode Map to JSON
var body = json.encode(data);
var response = await http.post(Uri.parse(url),
headers: {"Content-Type": "application/json"}, body: body);
if (response.statusCode == 200) {
var result = json.decode(response.body.toString());
if (result['ResponseCode'] == "0") {
/*ApiResponseData(
responseCode: "17", responseMsg: 'Event added to calender.');
return apiResponseData; */
} else if (result['ResponseCode'] == "1") {
apiResponseData.responseCode = result['ResponseCode'].toString();
apiResponseData.responseMsg = result['ResponseMsg'].toString();
return apiResponseData;
}
}
return apiResponseData;
}
}
2nd code for call api_addEvent.dart
Future<void> _addEventToCalender(String date, String time,
int eventDateEpocMilisecond, String previousEventDocID) async {
setState(() {
_progressBarActive = true;
});
var result = await ApiAddEventToCalender().addEventToCalender(
widget.token, date, time, previousEventDocID, eventDateEpocMilisecond);
if (result.responseCode == "0") {
} else {
if (result.responseCode == "1") {
Navigator.of(context).pushNamedAndRemoveUntil(
'/social_signin', (Route<dynamic> route) => false);
} else {
showMessageDialogBox(context, result.responseMsg.toString());
}
}
setState(() {
_progressBarActive = false;
});
}
I want to ask how to fix this error message. I tried to fix it but still had no success. For example ApiResponseData (
responseCode: "17", responseMsg: "Event title is required."); will appear the message "Event title is required." if I do not enter a title. But for unknown errors, I'm not sure I should always show near this page. Can someone help me?
Related
Here is the file causing the problem:
import 'package:http/http.dart' as http;
import './question_model.dart';
import 'dart:convert';
class DBconnect {
final url = Uri.parse(
'https://quizzapp-f2354-default-rtdb.firebaseio.com/questions.json');
Future<List<Question>> fetchQuestions() async {
return http.get(url).then((response) {
var data = json.decode(response.body) as Map<String, dynamic>;
List<Question> newQuestions = [];
data.forEach((key, value) {
var newQuestion = Question(
id: key,
title: value['title'],
options: Map.castFrom(value['options']),
);
newQuestions.add(newQuestion);
});
return newQuestions;
});
}
}
Here's the JSON file that I loaded into the firebase realtime database:
{
"questions": {
"first": {
"title": "Who is the best player in the world?",
"options": {
"messi": "true",
"ronaldo": "false",
"haaland": "false",
"mbappe": "false"
}
},
"second": {
"title": "2 + 2 = ?",
"options": {
"1": "false",
"2": "false",
"3": "false",
"4": "true"
}
}
}
}
I tried running the app and was expecting the questions to load in the app.
/// A problem occurred because the API was not working properly, replace your code with this and try
class DBconnect {
final url = Uri.parse('https://quizzapp-f2354-default-rtdb.firebaseio.com/questions.json');
Future<List<Question>> fetchQuestions() async {
return http.get(url).then((http.Response? response) {
if (response?.statusCode == 200 || response?.statusCode == 201) {
var data = json.decode(response!.body) as Map<String, dynamic>;
List<Question> newQuestions = [];
data.forEach((key, value) {
var newQuestion = Question(
id: key,
title: value['title'],
options: Map.castFrom(value['options']),
);
newQuestions.add(newQuestion);
});
return newQuestions;
} else {
return [];
}
});
}
}
I'm registering user and I want to show user a message through json. How I'll show. Kindly check if there is any modification need regarding coding as I'm new in flutter.
Thanks.
void _registration() async {
String name = _nameController.text.trim();
String email = _emailController.text.trim();
String password = _passwordController.text.trim();
String phone = _phoneController.text.trim();
if (name.isEmpty) {
Utils.flushBarErrorMessage("Type your name", context);
} else if (email.isEmpty) {
Utils.flushBarErrorMessage("Type your email", context);
} else if (!GetUtils.isEmail(email)) {
Utils.flushBarErrorMessage("Type valid email address", context);
} else if (password.isEmpty) {
Utils.flushBarErrorMessage("Type your password", context);
} else if (password.length < 6) {
Utils.flushBarErrorMessage(
"password can't be less than 6 characters", context);
} else if (phone.isEmpty) {
Utils.flushBarErrorMessage("Type your phone", context);
} else {
var connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.mobile ||
connectivityResult == ConnectivityResult.wifi) {
ApiCall.signUp(name, email, password, phone).then((value) async {
if (value.statusCode == 200) {
if (json.decode(value.body)['success'] != null) {
if (json.decode(value.body)["success"]) {
RegisterResponse registerResponseModel =
RegisterResponse.fromJson(json.decode(value.body));
} else {
Utils.flushBarErrorMessage(
json.decode(value.body)["en_message"], context);
print(json.decode(value.body).toString());
}
}
} else {
Utils.flushBarErrorMessage('invalid data', context);
print(json.decode(value.body).toString());
}
});
} else {
Utils.flushBarErrorMessage("No Internet", context);
}
}
}
My registration Api response
{
"success": true,
"en_message": "",
"ar_message": "",
"data": {
"user": {
"first_name": "yt",
"username": "",
"email": "yat#gmail.com",
"type": 1,
"role_id": 4,
"verification_code": 9141,
"verified": 0,
"phone": "123456",
"updated_at": "2022-07-06T09:56:49.000000Z",
"created_at": "2022-07-06T09:56:49.000000Z",
"id": 140,
"balance": [
{
"AED": 0
}
]
}
},
"status": 200
}
My Response Model
class RegisterResponse {
RegisterResponse({
bool? success,
String? enMessage,
String? arMessage,
Data? data,
int? status,
}) {
_success = success;
_enMessage = enMessage;
_arMessage = arMessage;
_data = data;
_status = status;
}
RegisterResponse.fromJson(dynamic json) {
_success = json['success'];
_enMessage = json['en_message'];
_arMessage = json['ar_message'];
_data = json['data'] != null ? Data.fromJson(json['data']) : null;
_status = json['status'];
}
bool? _success;
String? _enMessage;
String? _arMessage;
Data? _data;
int? _status;
RegisterResponse copyWith({
bool? success,
String? enMessage,
String? arMessage,
Data? data,
int? status,
}) =>
RegisterResponse(
success: success ?? _success,
enMessage: enMessage ?? _enMessage,
arMessage: arMessage ?? _arMessage,
data: data ?? _data,
status: status ?? _status,
);
bool? get success => _success;
String? get enMessage => _enMessage;
String? get arMessage => _arMessage;
Data? get data => _data;
int? get status => _status;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['success'] = _success;
map['en_message'] = _enMessage;
map['ar_message'] = _arMessage;
if (_data != null) {
map['data'] = _data?.toJson();
}
map['status'] = _status;
return map;
}
}
en_message should have a value in response.
Your enMessage is empty, that's why you didn't get any message.
Use this inside snackbar, if content is not null
registerResponseModel.enMessage
.
I am new to flutter and am trying to receive a response that is returned when I do a post request. I want to display the response object in a preview modal however, i am stuck on how to go about it. I have so far been able to hit the post endpoint successfully and a console.log shows me the response as I expected. How can I receive the response and assign it to a variable that I can then pass to a view modal?
Here is what I have done so far:
/* The Post DbRequest */
Future < Reservation ? > priceReservation(Reservation priceReservation) async {
var content = jsonEncode(priceReservation.toJson());
const baseUrl = ApiEndPoint.baseUrl;
searchUrl = '$baseUrl/reservation/price';
var response = await http.post(
Uri.parse(searchUrl),
body: content,
headers: {
"Content-Type": "application/json"
},
);
final data = json.decode(response.body);
if (response.statusCode == 202) {
print(data);
return data;
} else
print(data);
return null;
}
/* The Post Service */
priceReservation(priceReservation) async {
ReservationDbRequests requests = ReservationDbRequests();
Reservation ? reservation =
await requests.priceReservation(priceReservation);
return reservation;
}
/* How can I receive the response in this save method and assign it the data variable */
_save() async {
if (_formKeyBooking.currentState!.validate()) {
Reservation reservationObject = new Reservation(
roomId: _roomController.text,
email: _emailController.text,
quantity: _quantityController.text.toString(),
checkInDate: DateTime.parse(_checkInController.text),
checkOutDate: DateTime.parse(_checkOutController.text),
);
Response data = await Provider.of < BookingService > (context, listen: false)
.priceReservation(reservationObject);
print(data);
setState(() {
_isLoading = false;
});
toastMessage(ToasterService.successMsg);
} else {
toastMessage(ToasterService.errorMsg);
}
}
// Here is my response
{
"id": "c204b78b-cae3-44ea-9aaf-2f439488fef9",
"email": "adeleke#email.com",
"quantity": 1,
"nights": 5,
"totalPricePerRoomPerNight": 134.07,
"totalPrice": {
"rooms": 615.0,
"discounts": 0.0,
"taxes": 55.35,
"total": 670.35
},
"room": {
"id": "d54986a8-4e00-4332-8edc-acf6e380f6c4",
"name": "villa",
"price": 123.0
},
"checkInDate": "2021-09-29T12:00:00+03:00",
"checkOutDate": "2021-10-04T12:00:00+03:00",
"taxes": [
{
"name": "room services",
"percent": 9.0,
"amount": 11.07
}
],
"discounts": []
}
will this help? check this artilcle for json serilization for complex response
Future <Map<String,dynamic>?> priceReservation(Reservation priceReservation) async {
//you API access code goes here
//check the status first before decoding
if (response.statusCode == 200) { //got the response with data
return json.decode(response.body);
} else if (response.statusCode == 204) { //got the response but no data
return null;
} else { //throw exception for other status code
throw 'error';
}
}
/* The Post Service */
Future<Map<String,dynamic>?> priceReservation(priceReservation) async {
ReservationDbRequests requests = ReservationDbRequests();
Map<String,dynamic>? response =
await requests.priceReservation(priceReservation);
return response;
}
//view
Map<String,dynamic>?> response = await Provider.of < BookingService > (context, listen: false)
.priceReservation(reservationObject);
print(response); //now it should be a Map
if(response != null){
print(response); //all response
print(response['id']); //access id
print(response['email']); //access email
print(response['room']['name']); //access room name
}
I have created a Cloudant service and credentials (1) along with a database and a couple of documents. I want to access that database from an IBM Cloud Function so created a function to do that. I tested the function by adding the copied and pasted credentials from (1) into the "Invoke with credentials" box (along with the and the db name and a valid docid). The function seems to take all that info correctly but I get a 401 error... any help would be massively appreciated!
{
"error": {
"description": "couch returned 401",
"errid": "non_200",
"error": "unauthorized",
"headers": {
"cache-control": "must-revalidate",
"content-type": "application/json",
"date": "Sat, 30 May 2020 16:37:25 GMT",
"statusCode": 401,
"strict-transport-security": "max-age=31536000",
"uri": "xxxxxxx",
"via": "1.1 lb1.bm-cc-eu-gb-04 (Glum/1.89.6)",
"www-authenticate": "Basic realm=\"Cloudant Private Database\"",
"x-cloudant-action": "cloudantnosqldb.any-document.read",
"x-cloudant-backend": "bm-cc-eu-gb-04",
"x-cloudant-request-class": "lookup",
"x-content-type-options": "nosniff",
"x-couch-request-id": "03e7fe91bb"
},
"message": "_reader access is required for this request",
"name": "Error",
"reason": "_reader access is required for this request",
"request": {
"headers": {
"accept": "application/json",
"content-type": "application/json"
},
"method": "GET",
"uri": "xxxxx"
},
"scope": "couch",
"stack": "Error: _reader access is required for this request\n at Object.clientCallback (/node_modules/#cloudant/cloudant/node_modules/nano/lib/nano.js:151:15)\n at Request._callback (/node_modules/#cloudant/cloudant/lib/clientutils.js:162:11)\n at Request.self.callback (/node_modules/request/request.js:185:22)\n at Request.emit (events.js:198:13)\n at Request.self._source.emit (/node_modules/#cloudant/cloudant/lib/eventrelay.js:78:21)\n at Request.<anonymous> (/node_modules/request/request.js:1161:10)\n at Request.emit (events.js:198:13)\n at Request.self._source.emit (/node_modules/#cloudant/cloudant/lib/eventrelay.js:78:21)\n at IncomingMessage.<anonymous> (/node_modules/request/request.js:1083:12)",
"statusCode": 401
}
}
The function code is as follows:
/**
* Read a document in Cloudant database:
* https://docs.cloudant.com/document.html#read
**/
function main(message) {
var cloudantOrError = getCloudantAccount(message);
if (typeof cloudantOrError !== 'object') {
return Promise.reject(cloudantOrError);
}
var cloudant = cloudantOrError;
var dbName = message.dbname;
var docId = message.docid || message.id;
var params = {};
if (!dbName) {
return Promise.reject('dbname is required.');
}
if (!docId) {
return Promise.reject('docid is required.');
}
var cloudantDb = cloudant.use(dbName);
if (typeof message.params === 'object') {
params = message.params;
} else if (typeof message.params === 'string') {
try {
params = JSON.parse(message.params);
} catch (e) {
return Promise.reject('params field cannot be parsed. Ensure it is valid JSON.');
}
}
return readDocument(cloudantDb, docId, params);
}
function readDocument(cloudantDb, docId, params) {
return new Promise(function (resolve, reject) {
cloudantDb.get(docId, params, function (error, response) {
if (!error) {
resolve(response);
} else {
console.error('error', error);
reject(error);
}
});
});
}
function getCloudantAccount(params) {
var Cloudant = require('#cloudant/cloudant');
var cloudant;
if (!params.iamApiKey && params.url) {
cloudant = Cloudant(params.url);
} else {
checkForBXCreds(params);
if (!params.host) {
return 'Cloudant account host is required.';
}
if (!params.iamApiKey) {
if (!params.username || !params.password) {
return 'You must specify parameter/s of iamApiKey or username/password';
}
}
var protocol = params.protocol || 'https';
if (params.iamApiKey) {
var dbURL = `${protocol}://${params.host}`;
if (params.port) {
dbURL += ':' + params.port;
}
cloudant = new Cloudant({
url: dbURL,
plugins: {iamauth: {iamApiKey: params.iamApiKey, iamTokenUrl: params.iamUrl}}
});
} else {
var url = `${protocol}://${params.username}:${params.password}#${params.host}`;
if (params.port) {
url += ':' + params.port;
}
cloudant = Cloudant(url);
}
}
return cloudant;
}
function checkForBXCreds(params) {
if (params.__bx_creds && (params.__bx_creds.cloudantnosqldb || params.__bx_creds.cloudantNoSQLDB)) {
var cloudantCreds = params.__bx_creds.cloudantnosqldb || params.__bx_creds.cloudantNoSQLDB;
if (!params.host) {
params.host = cloudantCreds.host || (cloudantCreds.username + '.cloudant.com');
}
if (!params.iamApiKey && !cloudantCreds.apikey) {
if (!params.username) {
params.username = cloudantCreds.username;
}
if (!params.password) {
params.password = cloudantCreds.password;
}
} else if (!params.iamApiKey) {
params.iamApiKey = cloudantCreds.apikey;
}
}
}
Basically, copying and pasting those credentials led to it not working. Not sure why. To get a test invocation working I added url, docid, dbname, host, url and iamApiKey values to the parameters section of the function. That worked.
In my code I need to update the model
{
"customerCode": "CUS15168",
"customerName": "Adam Jenie",
"customerType": "Cash",
"printPackingSlip": "true",
"contacts": [
{
"firstName": "Hunt",
"lastName": "Barlow",
"email": "huntbarlow#volax.com",
"deliveryAddress": "805 Division Place, Waumandee, North Carolina, 537",
},
{
"firstName": "Barlow",
"lastName": "Hunt",
"email": "huntbarlow#volax.com",
"deliveryAddress": "805 Division Place, Waumandee, North Carolina, 537",
}
],
"deliveryAddress": [
{
"addressName": "Postal",
"addressType": "postal address",
"addressLine1": "plaza street",
"addressLine2": "broome street",
"suburb": "Guilford",
"city": "Oneida",
"state": "Colorado",
"postalCode": "3971",
"country": "Belarus",
"deliveryInstruction": "test delivery address"
},
{
"addressName": "Physical",
"addressType": "physical address",
"addressLine1": "plaza street",
"addressLine2": "broome street",
"suburb": "Guilford",
"city": "Oneida",
"state": "Colorado",
"postalCode": "3971",
"country": "Belarus",
"deliveryInstruction": "test delivery address"
}
]
}
I used promise all to achieve that. In postman, I send this object, but first it needs to add the customer, the contact array and then delivery address array. I did it as follows.
public async createCustomer(customer: CustomerDTO): Promise<CustomerDTO> {
let deliveryAddress = [];
let contacts = [];
let customerDto = new CustomerDTO();
customerDto.customerCode = customer.customerCode;
customerDto.tenantId = customer.tenantId;
if (customer.contacts.length > 0) {
customer.contacts.map((element => {
contacts.push(element);
}));
customer.contacts.length = 0;
}
if (customer.deliveryAddress.length > 0) {
customer.deliveryAddress.map((element => {
deliveryAddress.push(element);
}));
customer.deliveryAddress.length = 0;
}
const createdCustomer = await this.customerRepo.updateOrCreateCustomer(customer);
let updatedAddress = deliveryAddress.map(async (address: CustomerDeliveryAddressDto) => {
return await this.customerRepo.updateDeliveryAddress(address, customerDto, address._id);
});
let updatedContacts = contacts.map(async (contact: CustomerContactsDto) => {
return await this.customerRepo.createOrUpdateContactList(contact, customerDto, contact._id);
});
return Promise.all([updatedAddress, updatedContacts]).
then((results: [Promise<boolean>[], Promise<boolean>[]]) => {
console.log(results);
return this.customerRepo.getLastUpdatedCustomer();
}).
then((result) => {
return result;
}).
catch(e => {
console.error(e);
return e;
});
}
In customerRepository
public async updateDeliveryAddress(deliveryAddressDto: CustomerDeliveryAddressDto, customerDto: CustomerDTO, deliveryAddressId: string): Promise<boolean> {
const customerToBeUpdated = await this.model.findOne({
customerCode: customerDto.customerCode,
tenantId: customerDto.tenantId
});
if (customerToBeUpdated !== null) {
if (deliveryAddressId != null || deliveryAddressId != undefined) {
const result = await this.model.findOneAndUpdate({ _id: customerToBeUpdated._id, deliveryAddress: { $elemMatch: { _id: deliveryAddressId } } },
{
$set: {
//code here
}
},
{ 'new': true, 'safe': true, 'upsert': true });
if (result){
return true;
}
} else {
const result = await this.model.findOneAndUpdate({ _id: customerToBeUpdated._id },
{
$push: { deliveryAddress: deliveryAddressDto }
},
{ 'new': true, 'safe': true, 'upsert': true }
);
if (result) {
return true;
}
}
} else {
return false;
}
}
The problem is that it does not resolve all the methods when it goes to promise all method and I need to get the last updated customer, but it gives the result DeliveryAddress and contacts with empty arrays. Customer document on mongodb is updated as needed.
You need to pass the promises directly in a flat array.
Promise.all on MDN
If the iterable contains non-promise values, they will be ignored, but still counted in the returned promise array value (if the promise is fulfilled)
You can do this easily using the spread operator.
let updatedAddress = deliveryAddress.map(async (address: CustomerDeliveryAddressDto) => {
return await this.customerRepo.updateDeliveryAddress(address, customerDto, address._id);
});
let updatedContacts = contacts.map(async (contact: CustomerContactsDto) => {
return await this.customerRepo.createOrUpdateContactList(contact, customerDto, contact._id);
});
// need to give a flat array to Promise.all, so use the `...` spread operator.
return Promise.all([...updatedAddress, ...updatedContacts]).then(/* ... */
Also, since you are already using async / await, no reason you cannot await the Promise.all call.
const results = await Promise.all([...updatedAddress, ...updatedContacts]);
console.log(results);
return this.customerRepo.getLastUpdatedCustomer();
You can also nest Promise.all
let updatedAddress = Promise.all(deliveryAddress.map(async (address: CustomerDeliveryAddressDto) => {
return await this.customerRepo.updateDeliveryAddress(address, customerDto, address._id);
}));
let updatedContacts = Promise.all(contacts.map(async (contact: CustomerContactsDto) => {
return await this.customerRepo.createOrUpdateContactList(contact, customerDto, contact._id);
}));
return Promise.all([updatedAddress, updatedContacts])