How can i fetch datas positioned in list and send it to another api's query parameter? - arrays

i need to fetch a string data from an api (this data located in a list) and i need to send this data to another api as a query parameter. I dunno how to send this as query parameter because this data positioned in a list.
For a better understating : in this api there is a key named steamid i need to fetch this steam id each time and send those as a parameter to this api
class GDCubit extends Cubit<GDState> {
GDCubit({
required this.steamService,
required this.steamReviews,
}) : super(GDInitial()) {
emit(GDInitial());
}
final SteamService steamService;
final SteamReviews steamReviews;
late final steamdata;
late final steamreview;
late final player;
late String appId = '2208920';
late String userId = '76561198078971744';
late String? id = steamReviews.reviews![0].author?.steamid; // I tried to send first users steam id but cannot initialize
void getDatas() async {
try {
emit(GDLoading());
steamdata = await steamService.fetchRelatedAppWithId(appId);
steamreview = await steamService.fetchSteamReviewsRelatedAppId(appId);
player = await steamService.fetchPlayerInfo(id);
//player = await steamService.fetchPlayerInfo(userId); //works properly but manually
emit(GDLoaded(steamdata, steamreview, player));
} catch (e) {
return print('${e.toString()}' 'Error');
}
}
}
`
I tried to send steamid of first user in list but cannot initialize it

Are you trying to initialize the variable id before steamReviews, try creating the id inside your getDatas method, like this:
class GDCubit extends Cubit<GDState> {
GDCubit({
required this.steamService,
required this.steamReviews,
}) : super(GDInitial()) {
emit(GDInitial());
}
final SteamService steamService;
final SteamReviews steamReviews;
late final steamdata;
late final steamreview;
late final player;
late String appId = '2208920';
late String userId = '76561198078971744';
void getDatas() async {
try {
emit(GDLoading());
steamdata = await steamService.fetchRelatedAppWithId(appId);
steamreview = await steamService.fetchSteamReviewsRelatedAppId(appId);
final id = steamReviews.reviews![0].author?.steamid; // Create id here
player = await steamService.fetchPlayerInfo(id);
emit(GDLoaded(steamdata, steamreview, player));
} catch (e) {
return print('${e.toString()}' 'Error');
}
}
}

Related

How can I update a data with SQFLite in Flutter?

static Future<int?> update(
String cariadi,
) async {
var dbClient = await _db;
return await dbClient?.rawUpdate('UPDATE $_tableName SET $cariadi = ');
}
This is how I created the database
void getCari() async {
List<Map<String, dynamic>> cariler = await DBCari.query();
cariList.assignAll(cariler.map((data) => Cari.fromJson(data)).toList());
}
void updateData(Cari cari) {
DBCari.update(cari.cariadi!);
getCari();
}
Try to connect value = key by creating a controller named CariController.
final _cariController = Get.put(CariController());
onTap: () {
_cariController.update();
},
Finally, I wanted to enable the user to edit the data entered by clicking on the edit part in a button I wanted. But nothing happened when the button was clicked.
What kind of code do I need to write in the database, controller and homepage I created so that the user can edit and update the data entered?
here is a reference :
Future<int> update(Map<String, dynamic> row) async {
Database db = await instance.database;
int id = row[columnId];
return await db.update(table, row, where: '$columnId = ?', whereArgs: [id]);
}
https://github.com/DaymaManish/flutter_sqflite_crud/blob/main/lib/db_manager.dart

How to send variable amount of ether to smart contract from React front end?

I am trying to send a variable amount of ether from my React front end to my smart contract. In remix, I can do this no problem by just selecting the amount and sending it with the function
In my front end, this is the function where values.amount is 100wei
const sendEth = async(e) => {
e.preventDefault()
try {
const { ethereum } = window;
if (ethereum) {
const provider = new ethers.providers.Web3Provider(ethereum);
const signer = provider.getSigner();
const connectedContract = new ethers.Contract(CONTRACT_ADDRESS, escrowAbi.abi, signer);
let nftTxn = await connectedContract.depositEth(values.amount);
console.log("Mining...please wait.", nftTxn)
await nftTxn.wait();
console.log(`Mined, see transaction: https://rinkeby.etherscan.io/tx/${nftTxn.hash}`);
// console.log(connectedContract)
} else {
console.log("Ethereum object doesn't exist!");
}
} catch (error) {
console.log(error)
}
}
In my smart contract this is my depositEth function - however msg.value is argument i want to pass but I can't pass this as an argument to this function?
FYI in my app, once you they pay eth to the contract it will release an NFT.
function depositEth() public payable hasToken(address(this), nftAddress) {
require(msg.value == amountOwed, 'You ow more money');
buyerAddress = payable(msg.sender);
if(walletHoldsToken(address(this),nftAddress)) {
ERC721(nftAddress).safeTransferFrom(address(this), buyerAddress, tokenID);
}
}
So what I am asking is how do I send x amount of eth to a contract with that value defined in the front end?
In your smart contract define a function to return the amount that owed:
function getOwedAmount() public view returns (uint256) {
// i am assuming " amountOwed" is state variable, uint256
return amountOwed;
}
After creating the contract.
const connectedContract = new ethers.Contract(CONTRACT_ADDRESS, escrowAbi.abi, signer)
get the owned amount
let owedAmount = await contract.getOwedAmount();
owedAmount=owedAmount.toString()
let transaction=await connectedContract.depositEth({value:owedAmount})
await transaction.wait();
since depositEth is payable we can pass last argument as an object specifying how much we send and solidity will automatically assign that amount to msg.value
Your depositEth() function takes 0 params, so the JS snippet also needs to pass 0 params.
There's the overrides object in ethers, always passed after the regular function params (in your case on the 1st place as there are 0 params), allowing to modify certain fields of the transaction invoking the function, including its value.
let nftTxn = await connectedContract.depositEth({
value: values.amount
});

Flutter multipart/form-data send list of items

My using package http
I have this method in my app to send post request with files. In my case I send files and also fields with dynamic values. I tried send List<String> but server (backend) return me error with message:
The seedlings field must be an array.
Example seedlings list value:
List<String> seedlings = ['Apple', 'Banana'];
Code:
Future post(String path, data) async {
await _getToken();
var url = '${ApiConstants.BASE_URL}$path';
var uri = Uri.parse(url);
var request = MultipartRequest('POST', uri);
data.forEach((key, item) async {
if (item == null) return null;
if (item is File) {
request.files.add(await MultipartFile.fromPath(
'file',
item.path,
));
} else {
request.fields[key] = item is num
? item.toString()
: item is List
? item.toString()
: item;
}
});
request.headers['Content-type'] = 'application/json';
request.headers['Accept'] = 'application/json';
var response = await request.send();
}
In my case all fields sent to server except fields with list of values like array
This might be old, but you can easily do this by adding the array items into a form data array
final FormData formData = FormData({});
// Add all normal string request body data
formData.fields.add(MapEntry("name", "Olayemii"));
formData.fields.add(MapEntry("age", 99));
// Add all files request body data
formData.files.add(MapEntry("profile_photo", file));
// Add the array item
List<String> seedlings = ['Apple', 'Banana'];
seedlings.forEach((element) {
formData.fields.add(MapEntry("seedlings[]", element.toString()));
});
I have found an answer for this which I have posted in another similar question. I'll just put the code snippet here.
final request = http.MultipartRequest('Post', uri);
List<String> ManageTagModel = ['xx', 'yy', 'zz'];
for (String item in ManageTagModel) {
request.files.add(http.MultipartFile.fromString('manage_tag_model', item));
}
Basically you have to add the list as files with fromString() method.
Find the original answer here-
https://stackoverflow.com/a/66318541/7337717

How to parse this JSON Array in Flutter?

I am working with Flutter and am currently trying to create a graph. I am looking to parse this JSON Array from the link below. My issue is that the information provided in the "prices" object, the values are all inside arrays themselves. I want to get those values and split them into an X and Y list but I have no idea how to accomplish this. I posted a snippet of the JSON data below.
https://api.coingecko.com/api/v3/coins/bitcoin/market_chartvs_currency=usd&days=1
I am only familiar with parsing data by creating a class and constructor. Then create a fromJSON(Map<String, dynamic> json) class and putting the data into a list, as shown in the code snippet below that I created from another URL with object values. How could I go about parsing this array JSON data into two list data?
CODE TO PARSE JSON
List<Coins> _coins = List<Coins>();
Future<List<Coins>> fetchCoins() async {
var url = 'URL';
var response = await http.get(url);
var coins = List<Coins>();
if (response.statusCode == 200) {
var coinsJSON = json.decode(response.body);
for (var coinJSON in coinsJSON) {
coins.add(Coins.fromJson(coinJSON));
}
}
return coins;
}
#override
void initState() {
fetchCoins().then((value) {
setState(() {
_coins.addAll(value);
});
});
super.initState();
}
class Coins{
String symbol;
String name;
Coins(this.symbol, this.name);
Coins.fromJson(Map<String, dynamic> json) {
symbol = json['symbol'];
name = json['name'];
JSON DATA SNIPPET
{
"prices":[
[
1566344769277,
10758.856131083012
],
[
1566345110646,
10747.91694691537
],
[
1566345345922,
10743.789313302059
],
]
}
EDIT: SOLVED WITH THE HELP OF #EJABU.
class HistoricalData {
List prices;
List<num> listX = [];
List<num> listY = [];
HistoricalData(this.prices,this.listX, this.listY);
HistoricalData.fromJson(Map<String, dynamic> json) {
prices = json['prices'];
for (var price in prices) {
listX.add(price[0]);
listY.add(price[1]);
}
}
You may try this...
New class Coins definition:
class Coins {
List<num> listX = [];
List<num> listY = [];
Coins(this.listX, this.listY);
Coins.fromJson(Map<String, dynamic> json) {
List<List<num>> prices = json['prices'];
for (var price in prices) {
listX.add(price[0]);
listY.add(price[1]);
}
}
}
Then later you can fetch it by these lines :
// Future<List<Coins>> fetchCoins() async { // Remove This
Future<Coins> fetchCoins() async {
var url = 'URL';
var response = await http.get(url);
// var coins = List<Coins>(); // Remove This
Coins coins;
if (response.statusCode == 200) {
var coinsJSON = json.decode(response.body);
// Remove This
// for (var coinJSON in coinsJSON) {
// coins.add(Coins.fromJson(coinJSON));
// }
//
coins = Coins.fromJSON(coinsJSON);
}
return coins;
}
Accessing Data in Widget
In Widgets , our expected variable resides as property inside Coins class.
For example, if you use FutureBuilder, you may use these lines:
child: FutureBuilder(
future: fetchCoins(),
builder: (_, __) {
return SomeChartWidget(
listX: coins.listX,
listY: coins.listY,
);
},
),
Generating Serializers automatically
I suggest you take a look at https://pub.dev/packages/json_serializable, which is a package that does the boilerplate code generation for you. Although it might me a bit overkill to add something like this to your code or your workflow, automatically generating serializers is very convenient.
Not that in order to have custom sub-classes, they need to provide serialization as well.
If you want to extend your knowledge even further, you can also have a look at https://pub.dev/packages/built_value and https://pub.dev/packages/built_value_generator

Byte array and JSON in [FromBody]

I am trying pass an object which consists of different data type. I am always getting null value for orderDetails in Web API.
However if do this,
purchaseOrder.Attachments = null,
in the client then orderDetails is no longer null and I have other informations like "SendEmail" and PurchaseOrderNumber.
It looks I might not be correctly set the parameter in the client (angular 2).
However testing the same Web Api method from Console app works fine and I am not getting a null value.
Do I need to separate the JSON data and byte array?
regards,
-Alan-
Models
public class Attachments
{
public int AttachmentId { get; set; }
public string FileName { get; set ;}
public byte[] FileData { get; set ;}
}
public class UpdatePurchaseOrderViewModel
{
public bool SendEmail { get; set; }
public int PurchaseOrderNumber { get; set; }
public Attachments Attachments { get; set;
}
Here is my Web API put method definition
[HttpPut("AddPurchaseOrderNumber/{purchaseOrderId}")]
public StatusCodeResult AddPurchaseOrderNumber(int purchaseOrderId, [FromBody] UpdatePurchaseOrderViewModel orderDetails)
{
try
{
var status = _service.AddPurchaseOrderNumber(purchaseOrderId, orderDetails);
if (status == 200)
_unitOfWorkAsync.SaveChanges();
else return StatusCode(status);//No Data
}
catch
{
return StatusCode(400); // Bad Request
}
return StatusCode(200);//OK
}
Typescript snippet
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept','application/json');
let options = new RequestOptions({ headers: headers });
var body = JSON.stringify(
purchaseOrder
);
var uri = 'http://localhost:33907/api/purchaseorder/addpurchaseordernumber/' + purchaseOrderId;
return this._http.put(uri, body , options)
.map((response: Response) => {
let data = response.json();
if (data) {
return true;
}
else {
return false;
}
})
Update
The orderDetails is created as below
let file = Observable.create((observer) => {
let fr = new FileReader();
let data = new Blob([this.attachment]);
fr.readAsArrayBuffer(data);
fr.onloadend = () => {
observer.next(fr.result);
observer.complete();
};
fr.onerror = (err) => {
observer.error(err);
}
fr.onabort = () => {
observer.error("aborted");
}
});
file.map((fileData) => {
//build the attachment object which will be sent to Web API
let attachment: Attachments = {
AttachmentId: '0',
FileName: this.form.controls["attachmentName"].value,
FileData: fileData
}
//build the purchase order object
let order: UpdatePurchaseOrder = {
SendEmail: true,
PurchaseOrderNumber:this.form.controls["purchaseOrderNumber"].value * 1, //for casting purpose
Attachments: attachment
}
console.log("Loading completed");
return order;
})
When sending objects that have byte arrays as a property back and forth between a client to a WebAPI endpoint, I typically use a DTO that stores the property to explicitly define it as a Base64 string. On the server side I map the DTO to my entity by converting the Base64 string to / from the byte array for server side operations and storing in the database.
The serializer will do something like this automatically but the format passed from JavaScript may not match what the WebAPI JSON serializer is expecting (which is why it's working from your C# Console App).
You didn't include how you are creating the purchaseOrder object in your JavaScript so I can't comment on how that object is being setup - which may be where your issue is.

Resources