Http Headers in GraphQL Flutter - android

I am working with GraphQL. I need to pass parameters to Http headers. However, I see an option to pass only normal parameters (code below). PLEASE tell me how to do it!!
Query(
options: QueryOptions(
document: gql(userGraphQL),
variables: {
"..." : "..."
}
),
builder: ...
)

I have created this file to related the GraphQL
gql_utils.dart file
class GraphQLUtils {
static final GraphQLUtils _instance = GraphQLUtils._internal();
GraphQLClient? _client;
factory GraphQLUtils() {
return _instance;
}
GraphQLUtils._internal() {
final httpLink = HttpLink(
'your base url',
);
final authLink = AuthLink(
ignore: undefined_identifier
getToken: () async => 'Bearer $YOUR_PERSONAL_ACCESS_TOKEN',
);
var link = authLink.concat(httpLink);
var link = httpLink;
var link = httpLink;
final policies = Policies(
fetch: FetchPolicy.networkOnly,
);
_client = GraphQLClient(
cache: GraphQLCache(),
link: link,
defaultPolicies: DefaultPolicies(
watchQuery: policies,
query: policies,
mutate: policies,
),
);
}
Future<Map<String, dynamic>> queryRepo(
DocumentNode readRepositories, map) async {
final options = WatchQueryOptions(
document: readRepositories,
variables: map,
pollInterval: const Duration(seconds: 4),
fetchResults: true,
);
QueryResult result = await _client!.query(options);
if (result.hasException) {
Map<String, dynamic> response = <String, dynamic>{};
response['success'] = false;
response['message'] = result.exception!.graphqlErrors[0].message;
return response;
} else {
Map<String, dynamic> response = <String, dynamic>{};
response['success'] = true;
response['data'] = result.data;
return response;
}
}
}
this is Example query class
class UserQueries {
static final userInsertQuery = gql(r'''
mutation Insert_users($objects: [users_insert_input!]!, $onConflict: users_on_conflict) {
insert_users(objects: $objects, on_conflict: $onConflict) {
returning {
id
name
timestamp
}
}
}
''');
}
and how to call api
Future insertUserApi(String name) async {
try {
Map<String, dynamic> variables = <String, dynamic>{};
variables = {
"objects": [
{"name": name}
],
"onConflict": {
"constraint": "users_pkey",
"update_columns": [
"id",
"name",
]
}
};
await GraphQLUtils()
.queryRepo(UserQueries.userInsertQuery, variables)
.then((response) async {
if (response["data"] != null) {
print("----Data---:${response["data"]}");
Get.back();
} else {
Get.snackbar(
"Error",
"Something Went wrong",
);
}
});
} catch (e, st) {
Get.snackbar(
"Error",
e.toString(),
);
}
}

Related

Unhandled exception: [type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String']

this is the json formate by which I need to get the data `
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"date": "2022-11-23",
"breaks_set": [],
"id": "c82af994-541a-40eb-a154-9cf8b130100c",
"clock_in_time": "2:30",
"clock_out_time": "6:30",
"on_time_clock_in": 553,
"on_time_clock_out": -313
},
{
"date": "2022-11-28",
"breaks_set": [
{
"start": "09:36:01",
"end": "09:40:12.632703",
"break_duration": 4
},
{
"start": "09:40:13.626539",
"end": "09:40:14.282107",
"break_duration": 0
},
{
"start": "09:40:14.764177",
"end": "09:40:15.606529",
"break_duration": 0
}
],
"id": "e1c21659-1c2f-4ecd-b56b-a45626bedd7c",
"clock_in_time": "9:36",
"clock_out_time": "9:40",
"on_time_clock_in": 128,
"on_time_clock_out": -124
}
]
}
`
The model class of the json is coded like this
class BreaksSet {
String? start;
String? end;
int? breakduration;
BreaksSet({this.start, this.end, this.breakduration});
BreaksSet.fromJson(Map<String, dynamic> json) {
start = json['start'];
end = json['end'];
breakduration = json['break_duration'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['start'] = start;
data['end'] = end;
data['break_duration'] = breakduration;
return data;
}
}
class Result {
String? date;
List<BreaksSet?>? breaksset;
String? id;
String? clockintime;
String? clockouttime;
int? ontimeclockin;
int? ontimeclockout;
Result(
{this.date,
this.breaksset,
this.id,
this.clockintime,
this.clockouttime,
this.ontimeclockin,
this.ontimeclockout});
Result.fromJson(Map<String, dynamic> json) {
date = json['date'];
if (json['breaks_set'] != null) {
breaksset = <BreaksSet>[];
json['breaks_set'].forEach((v) {
breaksset!.add(BreaksSet.fromJson(v));
});
}
id = json['id'];
clockintime = json['clock_in_time'];
clockouttime = json['clock_out_time'];
ontimeclockin = json['on_time_clock_in'];
ontimeclockout = json['on_time_clock_out'];
}
}
class Attendance {
int? count;
String? next;
String? previous;
List<Result?>? results;
Attendance({this.count, this.next, this.previous, this.results});
Attendance.fromJson(Map<String, dynamic> json) {
count = json['count'];
next = json['next'];
previous = json['previous'];
if (json['results'] != null) {
results = <Result>[];
json['results'].forEach((v) {
results!.add(Result.fromJson(v));
});
}
}
}
the api calling I used DIO and the method is, here I made a connection class that contains the dio codes of all type api calling
`
Future<List<Attendance>> getUserAttendanceData() async {
final response = await _connection.getDataWithToken(
"${KApiUrls.baseUrl}/attendance-list/",
token,
);
if (response != null) {
if (response.statusCode == 200
) {
var data = jsonDecode(response.data).cast<List<Map<String, dynamic>>>();
return List.from(
data.map((attendance) => Attendance.fromJson(attendance)));
} else {
throw Exception();
}
} else {
throw Error();
}
}
`
I am getting this error, I have to idea how to solve this, but I tried several solution for this
Once you call jsonDecode Map is retuned which could contain nested Map. You can use plugin to generate toMap(Map<String, dynamic>) method in your model class and use it.
Future<Attendance> getUserAttendanceData() async {
final response = await _connection.getDataWithToken(
"${KApiUrls.baseUrl}/attendance-list/",
token,
);
if (response != null) {
if (response.statusCode == 200) {
//modified and solved code
return Attendance.fromJson(response.data);
} else {
throw Exception();
}
} else {
throw Error();
}
}
I am expecting of list of objects but I got a object that contains list of objects

Flutter looping while i trying refresh token with dio interceptors

While i trying refresh my token with interceptors, its always looping. I dont know why. Firstly i want to show my code;
class ApiService {
final Dio _dio = Dio();
final Dio tokenDio = Dio();
int tryCount = 0;
String? accessToken;
String? refreshToken;
final _storage = const FlutterSecureStorage();
ApiService() {
_dio.options.baseUrl = ApiConstants.baseUrl;
tokenDio.options = _dio.options;
_storage.read(key: "token").then((value) => accessToken = value);
_storage.read(key: "refreshToken").then((value) => refreshToken = value);
_dio.interceptors.add(
QueuedInterceptorsWrapper(
onError: (DioError error, ErrorInterceptorHandler handler) async {
if (error.response?.statusCode == 401) {
log("Hata Aldık! ${error.requestOptions.path}");
RequestOptions options = error.response!.requestOptions;
if ("Bearer $accessToken" != options.headers[HttpHeaders.authorizationHeader]) {
log("token farklıydı! $accessToken / ${options.headers[HttpHeaders.authorizationHeader]} ");
options.headers[HttpHeaders.authorizationHeader] = "Bearer $accessToken";
_dio.fetch(options).then(
(value) => handler.resolve(value),
onError: (e) {
log("error on resolve");
handler.reject(e);
},
);
return;
}
_dio
.get("/Auth/RefreshTokenLogin?refreshToken=${Uri.encodeQueryComponent(refreshToken!)}")
.then((response) async {
log("Token Refreshlendi!");
if (response.statusCode == 200) {
final RefreshTokenResponseModel? model = RefreshTokenResponseModel.fromJson(response.data);
_storage.write(key: "token", value: model!.data!.token);
_storage.write(key: "refreshToken", value: model.data!.refreshToken);
refreshToken = model.data!.refreshToken;
accessToken = model.data!.token;
options.headers[HttpHeaders.authorizationHeader] = "Bearer ${model.data!.token}";
tokenDio.options.headers = options.headers;
// await UserSecureStorage.setField("token", model!.data!.token);
// await UserSecureStorage.setField("refreshToken", model.data!.refreshToken);
// final AuthService _authService = AuthService();
// await _authService.registerDevice();
if (model.data != null && model.data!.contractsToBeApproved!.isNotEmpty) {
final AuthController authController = Get.Get.find();
authController.contractsToBeApproved.value = model.data!.contractsToBeApproved!;
}
_dio.fetch(options).then(
(value) => handler.resolve(value),
onError: (e) {
handler.reject(e);
},
);
return;
}
return;
});
}
return handler.next(error);
},
onRequest: (RequestOptions options, RequestInterceptorHandler handler) {
log("istek atıldı. ${options.path}");
if (accessToken == null) {
_storage.read(key: "token").then((value) {
log("storage readed $value");
accessToken = value;
options.headers[HttpHeaders.authorizationHeader] = "Bearer $value";
tokenDio.options.headers = options.headers;
handler.next(options);
});
} else {
options.headers[HttpHeaders.authorizationHeader] = "Bearer $accessToken";
return handler.next(options);
}
},
),
);
}
Its my ApiService. And my goal is refreshing token. It might have multiple request in same time so I used "QueuedInterceptorsWrapper". After token expire, Its entering to error handler function and logging "Token Refreslendi" after token refresh api call.But after that if i click something for api call its looping infinitely. Whats wrong with my code ? Thanks for help :)

Parsing Nested JSON give Unhandled Exception

I am trying to parse complex Nested JSON, I have multiple classes to get down the JSON nests. I am looking for the numbers from this JSON
{
"data": {
"attributes": {
"last_analysis_stats": {
"harmless": 81,
"malicious": 2,
"suspicious": 0
}
}
}
}
but whenever I parse it, I get the error "Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Data'"
the code that I am using is below
_GoneSmishinState goneSmishinStateFromJson(String str) => _GoneSmishinState.fromJson(json.decode(str));
String goneSmishinStateToJson(_GoneSmishinState data) => json.encode(data.toJson());
String url = "https://urlhaus-api.abuse.ch/v1/urls/recent/"; //address for URL file
int harmless = 0;
Future<void> main() async {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key:key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: "Gone Smishin'",
home: GoneSmishin(),
);
}
}
class Data {
late Attributes attributes;
Data.fromJson(Map<String, dynamic> json)
: attributes = Attributes.fromJson(json["attributes"]);
Map<String, dynamic> toJson() => {
"attributes": attributes.toJson(),
};
}
class Attributes {
late LastAnalysisStats lastAnalysisStats;
Attributes.fromJson(Map<String, dynamic> json)
: lastAnalysisStats= LastAnalysisStats.fromJson(json["last_analysis_stats"]);
Map<String, dynamic> toJson() => {
"last_analysis_stats": lastAnalysisStats.toJson(),
};
}
class LastAnalysisStats {
late int harmless;
late int malicious;
late int suspicious;
LastAnalysisStats.fromJson(Map<String, dynamic> json)
: harmless= json["harmless"],
malicious= json["malicious"],
suspicious= json["suspicious"];
Map<String, dynamic> toJson() => {
"harmless": harmless,
"malicious": malicious,
"suspicious": suspicious,
};
}
String message = "";
String word = "";
bool isOn = false;
#override
void dispose() {
myController.dispose();
//super.dispose();
}
var data = '';
var attributes = '';
String virusTotal = "VirusTotal";
String list = "Whitelist";
final myController = TextEditingController();
class GoneSmishin extends StatefulWidget {
const GoneSmishin({Key? key}) : super(key: key);
#override
_GoneSmishinState createState() => _GoneSmishinState();
}
class _GoneSmishinState extends State<GoneSmishin> {
_GoneSmishinState({Key? key}) : super();
late Data data;
_GoneSmishinState.fromJson(Map<String, dynamic> json)
: data= Data.fromJson(json["data"]);
Map<String, dynamic> toJson() => {
"data": data.toJson(),
};
urlHausParseBox() async {
String url = myController.text;
var urlEncoded = base64.encode(utf8.encode(myController.text));
var urlNoPadding = urlEncoded.replaceAll(new RegExp(r'='), '');
final response2 = await http.get(
Uri.parse("https://www.virustotal.com/api/v3/urls/$urlNoPadding"),
headers: <String, String>{
'Accept': 'application/json',
'x-apikey': '11111111111111111111111111111111'
},
);
print(urlEncoded);
print(response2.body);
if (response2.statusCode == 200) {
setState(() {
final decoded = json.decode(response2.body);
data = decoded['data'];
});
if ((data.attributes.lastAnalysisStats.malicious + data.attributes.lastAnalysisStats.suspicious)>= 2) {
setState(() {
virusTotal = 'Found in VirusTotal - Possibly Malicious';
});
} else
if ((data.attributes.lastAnalysisStats.suspicious + data.attributes.lastAnalysisStats.suspicious) <= 1) {
setState(() {
virusTotal = 'Found in VirusTotal - Probably not Malicious';
print((data.attributes.lastAnalysisStats.suspicious + data.attributes.lastAnalysisStats.suspicious));
});
} else {
setState(() {
virusTotal = 'Not found in VirusTotal';
});
}
Try to chage this code
setState(() {
final decoded = json.decode(response2.body);
data = decoded['data'];
});
to
setState(() {
final decoded = json.decode(response2.body);
data = Data.fromJson(decoded['data']);
});

you dont have permission to access https://securegw-stage.paytm.in/theia/api/v1/showPaymentPage? on this server

I am trying to integrate paytm payment gateway in my flutter application by following all in one sdk developer documentation but getting the error on UI (Access Denied you don't have permission to access https://securegw-stage.paytm.in/theia/api/v1/showPaymentPage?mid=MID&orderId=ORDER_ID on this server)
Here is my payment config class code
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:paytm_allinonesdk/paytm_allinonesdk.dart';
class PaytmConfig {
final String _mid = MID;
final String _mKey = MKEY;
final String _website = "WEBSTAGING";
final String _url =
'http://flutter-paytm-backend.great-site.net/generateTxnToken'; //testing server
String get mid => _mid;
String get mKey => _mKey;
String get website => _website;
String get url => _url;
String getMap(double amount, String callbackUrl, String orderId) {
return json.encode({
"mid": mid,
"key_secret": mKey,
"website": website,
"orderId": orderId,
"amount": amount.toString(),
"callbackUrl": callbackUrl,
"custId": "9204473819624814",
});
}
Future<void> generateTxnToken(double amount, String orderId) async {
final callBackUrl =
'https://securegw-stage.paytm.in/theia/paytmCallback?ORDER_ID=$orderId';
final body = getMap(amount, callBackUrl, orderId);
try {
final response = await http.post(
Uri.parse(url),
body: body,
headers: {'Content-type': "application/json"},
);
String txnToken = response.body;
await initiateTransaction(orderId, amount, txnToken, callBackUrl);
} catch (e) {
print(e);
}
}
Future<void> initiateTransaction(String orderId, double amount,
String txnToken, String callBackUrl) async {
String result = '';
try {
var response = AllInOneSdk.startTransaction(
mid,
orderId,
amount.toString(),
txnToken,
callBackUrl,
true,
false,
);
response.then((value) {
// Transaction successfull
print(value);
}).catchError((onError) {
if (onError is PlatformException) {
result = onError.message! + " \n " + onError.details.toString();
print(result);
} else {
result = onError.toString();
print(result);
}
});
} catch (err) {
// Transaction failed
result = err.toString();
print(result);
}
}
}
Calling the function to initiate the transaction when the button is pressed
ElevatedButton(
onPressed: () async => {
if (_formKey.currentState!.validate())
{
await PaytmConfig().generateTxnToken(
double.parse(priceController.text.toString()),
ORDER_ID),
}
},
child: Text('Pay'),
)
And here is my app.js class code in backend
var express = require('express');
var port = process.env.PORT || 3000;
var app = express();
const https = require('https');
const checksum_lib = require('./checksum');
app.use(express.json());
app.use(express.urlencoded());
app.get('/', function(req, res) {
console.log(req);
res.send(JSON.stringify({ Hello: 'World' }));
});
app.post('/generateTxnToken', function(request, res) {
console.log(request.body);
var paytmParams = {};
var MID = request.body.mid;
var orderId = request.body.orderId;
var amount = parseFloat(String(request.body.amount));
var custId = request.body.custId;
var key_secret = request.body.key_secret;
var callbackUrl = request.body.callbackUrl;
var mode = request.body.mode;
var website = request.body.website;
var testing = String(request.body.testing);
console.log(callbackUrl);
console.log(mode);
paytmParams.body = {
/* for custom checkout value is 'Payment' and for intelligent router is 'UNI_PAY' */
"requestType": "Payment",
/* Find your MID in your Paytm Dashboard at https://dashboard.paytm.com/next/apikeys */
"mid": MID,
/* Find your Website Name in your Paytm Dashboard at https://dashboard.paytm.com/next/apikeys */
"websiteName": website == undefined ? "DEFAULT" : website,
/* Enter your unique order id */
"orderId": orderId,
/* on completion of transaction, we will send you the response on this URL */
// "callbackUrl": "https://mrdishant.com",
"callbackUrl": callbackUrl,
/* Order Transaction Amount here */
"txnAmount": {
/* Transaction Amount Value */
"value": amount,
/* Transaction Amount Currency */
"currency": "INR",
},
/* Customer Infomation here */
"userInfo": {
/* unique id that belongs to your customer */
"custId": custId,
},
};
console.log("Mode");
console.log(mode);
if (mode == "1") {
console.log("Mode 1 So Net Banking");
paytmParams.body[
"enablePaymentMode"] = [{
"mode": "NET_BANKING",
}]
} else if (mode == "0") {
console.log("Mode 0 So BALANCE");
paytmParams.body[
"enablePaymentMode"] = [{
"mode": "BALANCE",
}]
} else if (mode == "2") {
console.log("Mode 2 So UPI");
paytmParams.body[
"enablePaymentMode"] = [{
"mode": "UPI",
}]
} else if (mode == "3") {
console.log("Mode 3 So CC");
paytmParams.body[
"enablePaymentMode"] = [{
"mode": "CREDIT_CARD"
}]
}
console.log(JSON.stringify(paytmParams));
/**
* Generate checksum by parameters we have in body
* Find your Merchant Key in your Paytm Dashboard at https://dashboard.paytm.com/next/apikeys
*/
checksum_lib.genchecksumbystring(JSON.stringify(paytmParams.body), key_secret, (err, checksum) => {
if (err) {
return;
}
/* head parameters */
paytmParams.head = {
/* put generated checksum value here */
"signature": checksum
};
/* prepare JSON string for request */
var post_data = JSON.stringify(paytmParams);
var options = {
/* for Staging */
/* for Production */
hostname: testing == "0" ? 'securegw-stage.paytm.in' : 'securegw.paytm.in',
port: 443,
path: '/theia/api/v1/initiateTransaction?mid=' + MID + '&orderId=' + orderId,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': post_data.length
}
};
// Set up the request
var response = "";
var post_req = https.request(options, (post_res) => {
post_res.on('data', (chunk) => {
response += chunk;
});
post_res.on('end', () => {
console.log(orderId);
console.log(MID);
console.log('Response: ', response);
response = JSON.parse(response);
res.send(response.body.txnToken);
return 0;
});
});
// post the data
post_req.write(post_data);
post_req.end();
});
});
app.listen(port, function() {
console.log(`Example app listening on port !`);
});

Strange behavior of notifyListener

I have a list which is fetched from the server but when we get outside of the fetching method the list is initialized to default. I have noticed that the problem is with the notifyListeners() as here:
Does notifyListeners() sometimes complete asynchronously?
Interestingly, inside the fetching method the the list is ok.
class Products with ChangeNotifier {
List<Product> _loadedProducts = [];
Future<void> fetchAndSetProducts() async {
try {
var response =
await http.get(StoreServer.serverAddress + '/products.json');
final extractedData = json.decode(response.body) as Map<String, dynamic>;
List<Product> extractedList = [];
extractedData.forEach((key, value) {
_loadedProducts.add(Product(
id: key,
imageUrl: value['imageUrl'],
title: value['title'],
price: value['price'],
description: value['description'],
isFavorite: value['isFavorite']));
});
_loadedProducts = extractedList;
notifyListeners();
await Future.delayed(Duration(seconds: 1));
} catch (error) {
throw error;
}
}
#override
void didChangeDependencies() {
if (!isInit) {
setState(() {
isLoading = true;
});
test = Provider.of<Products>(context);
test.fetchAndSetProducts().then((_) {
print("fetched");
setState(() {
isLoading = false;
isInit = true;
});
});
}
super.didChangeDependencies();
}
You have a logic error. Check my comments..!
class Products with ChangeNotifier {
List<Product> _loadedProducts = [];
Future<void> fetchAndSetProducts() async {
try {
var response =
await http.get(StoreServer.serverAddress + '/products.json');
final extractedData = json.decode(response.body) as Map<String, dynamic>;
List<Product> extractedList = []; // it is an empty list
extractedData.forEach((key, value) {
_loadedProducts.add(Product( // you add elements to _loadedProducts
id: key,
imageUrl: value['imageUrl'],
title: value['title'],
price: value['price'],
description: value['description'],
isFavorite: value['isFavorite']));
});
_loadedProducts = extractedList; // you reassign _loadedProducts to the empty list "extractedList"
notifyListeners();
await Future.delayed(Duration(seconds: 1));
} catch (error) {
throw error;
}
}
Am I right? I think you have that error!

Categories

Resources