PACT-JVM problems with closeArray - pact

So I'm only starting to use JVM-PACT.
I'm trying to crate this JSON
{
"elements": [
{
"Location": {
"id": "loc_id1",
"Addr": {
"Addr1": {
"value": "545 Test Street"
},
"City": {
"value": "New York City"
},
"StateProvCd": {
"value": "NY"
},
"PostalCode": {
"value": "11111"
}
}
}
}
]
}
Trying to do this: but it keeps on crashing when trying to call closeArray()
DslPart body = new PactDslJsonBody()
.eachLike("elements")
.object("Location")
.stringType("id","loc_id1")
.object("Addr")
.object("Addr1")
.stringType("value", "545 Test Street")
.closeObject()
.object("City")
.stringType("value", "New York City")
.closeObject()
.object("StateProvCd")
.stringType("value", "NY")
.closeObject()
.object("PostalCode")
.stringType("value", "11111")
.closeObject()
.closeObject()
.closeObject()
.closeArray();
I know it says " can't call closeArray on an Object" but it is definitely trying to close the "eachLike"
java.lang.RuntimeException: Failed to invoke pact method
at au.com.dius.pact.consumer.PactProviderRule.getPacts(PactProviderRule.java:269)
at au.com.dius.pact.consumer.PactProviderRule$1.evaluate(PactProviderRule.java:145)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at au.com.dius.pact.consumer.PactProviderRule.getPacts(PactProviderRule.java:267)
... 17 more
Caused by: java.lang.UnsupportedOperationException: can't call closeArray on an Object
at au.com.dius.pact.consumer.dsl.PactDslJsonBody.closeArray(PactDslJsonBody.java:542)
... 22 more
Any suggestions would be very helpful

Don't you need to close the last object? The one within the array containing location? You're closing the Location ibject, but forgetting that you're not closing the object containing the Location. I know it's a tad confusing with the DSL because arrays opens up a new object, we might have to look into making that better.
DslPart body = new PactDslJsonBody()
.eachLike("elements")
// New Object in Array starts here
.object("Location")
.stringType("id","loc_id1")
.object("Addr")
.object("Addr1")
.stringType("value", "545 Test Street")
.closeObject()
.object("City")
.stringType("value", "New York City")
.closeObject()
.object("StateProvCd")
.stringType("value", "NY")
.closeObject()
.object("PostalCode")
.stringType("value", "11111")
.closeObject()
.closeObject()
.closeObject()
// Array object needs to close here
.closeObject()
.closeArray();

Related

Flutter Stripe how to set user's billing address and submit it along to create a paymentmethod?

I am having some trouble setting and submitting to the Stripe server my app's customer's billing address for the Card they chose to pay with.
The code below is what I have tried but failed:
Future<PaymentMethod> createPaymentMethod(BuildContext context,
Map<String, String> billingAddress, String name, String phoneNumber) async {
StripePayment.setStripeAccount(null);
// Here to add the credit Card
PaymentMethod paymentMethod = PaymentMethod();
print('This is in paymentMethod: ${paymentMethod.toJson()}');
paymentMethod = await StripePayment.paymentRequestWithCardForm(
CardFormPaymentRequest(),
).then((PaymentMethod paymentMethod) {
paymentMethod.billingDetails = BillingDetails(
address: BillingAddress(
line1: billingAddress['Address'],
city: billingAddress['City'],
state: billingAddress['State'],
postalCode: billingAddress['Zip Code']),
name: name,
phone: phoneNumber);
return paymentMethod;
}).catchError((e) {
print('Error Card: ${e.toString()}');
});
paymentMethod != null
? print('Success')
: AwesomeDialog(
context: context,
title: 'Uh oh! A wild error has appeared!',
desc:
'Seems like we cant process this card. Please double check your input or try a different card',
animType: AnimType.SCALE,
dialogType: DialogType.WARNING,
btnOkOnPress: () {})
.show();
return paymentMethod;
}
The payment method and payment Intent are all successful but in the Response Body from Stripe, I am still only getting:
"billing_details": {
"address": {
"city": null,
"country": "US",
"line1": null,
"line2": null,
"postal_code": null,
"state": null
},
"email": null,
"name": null,
"phone": null
},
On my Response POST body I am only having:
{
"amount": "5178",
"currency": "usd",
"payment_method": "some_payment_method_here",
"confirm": "true",
"confirmation_method": "manual",
"off_session": "false"
}
How should I set my code such that I have finally have the user's billing address in the Response Body so that I can have:
"billing_details": {
"address": {
"city": "Sesame Town",
"country": "US",
"line1": "123 Sesame Street",
"line2": null,
"postal_code": 12345,
"state": "Sesame State"
},
"email": "mayorOfSesameStreet#email.com",
"name": "Mayor Sesame",
"phone": 8889990000
},
Thanks in advance
I’m assuming you’re using the stripe_payment package (https://pub.dev/packages/stripe_payment)? If you already have the customer’s billing address, you can pre-fill it by setting CardFormPaymentRequest.prefilledInformation.billingAddress (https://pub.dev/documentation/stripe_payment/latest/stripe_payment/CardFormPaymentRequest-class.html). Here’s how it would look in your code:
PaymentMethod paymentMethod = PaymentMethod();
CardFormPaymentRequest req = CardFormPaymentRequest(
prefilledInformation: PrefilledInformation (
billingAddress: BillingAddress(
line1: billingAddress['Address'],
city: billingAddress['City'],
state: billingAddress['State'],
postalCode: billingAddress['Zip Code'],
name: name)));
paymentMethod = await StripePayment.paymentRequestWithCardForm(req).then((PaymentMethod paymentMethod) {
return paymentMethod;
}).catchError((e) {
print('Error Card: ${e.toString()}');
});

setState() or markNeedsBuild() called during build - When setting the value of a variable fetched from an API?

I have a few json objects here -
{
"error": "0",
"message": "Got it!",
"data": [
{
"status": false,
"_id": "5e004fc92638d21e5f7e2ffc",
"group_id": "5dfc7136790365f0955deb2b",
"date": "2019-12-23T00:00:00.000Z",
"title": "creating new task",
"priority": 4,
"description": "details",
"tasks": [],
"created_date": "2019-12-23T05:25:29.524Z",
"__v": 0
},
{
"status": false,
"_id": "5e004ff798224784c87baff0",
"group_id": "5dfc712d790365d5a55deb2a",
"date": "2019-12-23T00:00:00.000Z",
"title": "new task",
"priority": 5,
"description": "details",
"tasks": [],
"created_date": "2019-12-23T05:26:15.621Z",
"__v": 0
}
]
}
I am displaying the fetched data from these json objects in this method -
Widget listViewWidget(List<Post> data) {
....
}
My application uses a PageView widget which displays the json objects based on the date it was created ("created_date" parameter) this way -
. I have also defined an integer int numberOfTasksLeft; which should hold the value of data.length But i need it to update everytime I am navigating to a new page (previous or next page). If there are two json objects for one day, the integer should have value of 2, etc. Could i get a suggestion on how to correctly set the value of this integer?
I have tried to use setState method this way -
Widget listViewWidget(List<Post> data) {
//settervalue = data;
setState(() {
numberofTasks = data.length;
});
...
}
but this resulted in an error - setState() or markNeedsBuild() called during build.
Flutter just like JavaScript finishes the synchronous code first and then the asynchronous code in the next event loop. setState() or markNeedsBuild() called during build., this error occurs because even before the build finishes synchronously you are calling setState. So if you change the call to setState in an async block you solve this problem. Maybe in a hacky way though.
Widget listViewWidget(List<Post> data) {
Timer(Duration(seconds: 0), () {
setState(() {
//settervalue = data;
numberofTasks = data.length;
});
});
...
}
Defining the PageController and variables:
PageController controller = PageController();
var currentPageValue = 0.0;
Updating the variable when the PageView is scrolled.
controller.addListener(() {
setState(() {
currentPageValue = controller.page; or //numberofTasks = data.length;
});
});
This usually happened when you call setState before the widget build method is called.so make sure to setData/setState in didChangeDependencies() after widget is mounted
void didChangeDependencies(){
super.didChangeDependencies();
if(mounted){
//call setState here
}
}

Formatter called multiple times or too soon with `undefined`

I'm using OpenUI5. Using the formatter.js, I have formatted some text in my view.
But my formatter is called 3 times:
When I bind the model to panel control: oPanel.setModel(oModel, "data");
both sBirthday and sFormat are undefined.
After onInit() is finished and the view is rendered:
sBirthday is valorized correctly and sFormat is undefined
Again: both sBirthday and sFormat ara valorized correctly.
Why does this happen? Is it correct?
The app get an error, because the ageDescription() in the formatter, can't manage undefined values.
formatter.js
sap.ui.define([], function () {
"use strict";
return {
ageDescription : function (sBirthday, sFormat) {
do.something();
var sFromMyBd = moment(sBirthday, sFormat).fromNow();
do.something();
return sAge;
}
}
});
main.view.xml
<mvc:View
controllerName="controller.main"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<Panel id="user-panel-id">
<Input id="name-input-id" enabled="false" value="{data>/user/name}" />
<Label text="{i18n>age}: " class="sapUiSmallMargin"/>
<Label text="{
parts: [
{path: 'data>/user/birthday'},
{path: 'data>/user/dateFormat'}
],
formatter: '.formatter.ageDescription' }"/>
</Panel>
</mvc:View>
Main.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel",
"model/formatter"
], function (Controller, JSONModel, formatter) {
"use strict";
return Controller.extend("controller.main", {
formatter: formatter,
onInit: function () {
var oModel = new JSONModel();
var oView = this.getView();
oModel.loadData("model/data.json");
var oPanel = oView.byId("user-panel-id");
oPanel.setModel(oModel,"data");
do.something();
},
});
});
data.json
{
"user": {
"name": "Frank",
"surname": "Jhonson",
"birthday": "23/03/1988",
"dateFormat": "DD/MM/YYYY",
"enabled": true,
"address": {
"street": "Minnesota street",
"city": "San Francisco",
"zip": "94112",
"country": "California"
}
}
}
Set the model to the view only when the data request is completed:
onInit: function() {
const dataUri = sap.ui.require.toUri("<myNamespace>/model/data.json");
const model = new JSONModel(dataUri);
model.attachEventOnce("requestCompleted", function() {
this.getView().setModel(model);
}, this);
// ...
},
This ensures that the formatter is called only once (invoked by checkUpdate(true) which happens on binding initialization; see below), and no further changes are detected afterwards.
Additionally (or alternatively), make the formatter more defensive. Something like:
function(value1, value2) {
let result = "";
if (value1 && value2) {
// format accordingly ...
}
return result;
}
Why does this happen?
View gets instantiated.
onInit of the Controller gets invoked. Here, the file model/data.json is requested (model is empty).
Upon adding the view to the UI, UI5 propagates existing parent
models to the view.
Bindings within the view are initialized, triggering checkUpdate(/*forceUpdate*/true)src in each one of them.
Due to the forceUpdate flag activated, change event is fired, which forcefully triggers the formatters even if there were no changes at all:
[undefined, undefined] → [undefined, undefined]. - 1st formatter call
Fetching model/data.json is now completed. Now the model needs to checkUpdate again.
[undefined, undefined] → [value1, undefined] → change detected → 2nd formatter call
[value1, undefined] → [value1, value2] → change detected → 3rd formatter call
Now, given that you are trying to load a static JSON file into your project, it's better to maximize the usage of the manifest.json.
That way, you are sure that the data is already loaded and available in the model prior to any binding.
You achieve this by adding the JSON file as a data source under sap.app
manifest.json
"sap.app": {
"id": "com.sample.app",
"type": "application",
"dataSources": {
"data": {
"type": "JSON",
"uri": "model/data.json"
}
}
}
Now, simply add this dataSource called data as one of the models under sap.ui5.
"sap.ui5": {
"rootView": {
"viewName": "com.sample.app.view.App",
"type": "XML"
},
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "com.app.sample.i18n.i18n"
}
},
"data": {
"type": "sap.ui.model.json.JSONModel",
"dataSource": "data"
}
}
}
With this, you DON'T need to call this anymore:
var oModel = new JSONModel();
var oView = this.getView();
oModel.loadData("model/data.json");
var oPanel = oView.byId("user-panel-id");
oPanel.setModel(oModel,"data");
..as the data model we added in the manifest.json, is already visible to oView and oPanel right from the get go.
This way, it doesn't matter if the formatter gets called multiple times, as it would already have the data available to it right from the beginning.

Get State By Linearid corda version 3.1

I am trying to get a state by lineaId by getting a empty list:
my code:
val queryCriteria = QueryCriteria.LinearStateQueryCriteria(uuid = listOf(linearId.id))
val customerAuditor = serviceHub.vaultService.queryBy<CustomerAuditor>(queryCriteria).states.single()
Error:
java.util.NoSuchElementException: List is empty.
at kotlin.collections.CollectionsKt___CollectionsKt.single(_Collections.kt:472) ~[kotlin-stdlib-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at com.hsbc.auditorFlow.updateCustomerInit$Initiator.call(UpdateCustomerAuditorInit.kt:59) ~[cordapp-customer-0.1.jar:?]
at com.hsbc.auditorFlow.updateCustomerInit$Initiator.call(UpdateCustomerAuditorInit.kt:31) ~[cordapp-customer-0.1.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:96) [corda-node-3.1-corda.jar:?]
at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:44) [corda-node-3.1-corda.jar:?]
at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092) [quasar-core-0.7.9-jdk8.jar:0.7.9]
at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788) [quasar-core-0.7.9-jdk8.jar:0.7.9]
at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100) [quasar-core-0.7.9-jdk8.jar:0.7.9]
at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91) [quasar-core-0.7.9-jdk8.jar:0.7.9]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_144]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_144]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_144]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [?:1.8.0_144]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_144]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_144]
at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:62) [corda-node-3.1-corda.jar:?]
When i do get all states the state is present:
val generalCriteria = QueryCriteria.VaultQueryCriteria(Vault.StateStatus.UNCONSUMED)
var pageNumber = DEFAULT_PAGE_NUM
val states = mutableListOf<StateAndRef<ContractState>>()
do {
val pageSpec = PageSpecification(pageSize = 200, pageNumber = pageNumber)
val results = services.vaultQueryByWithPagingSpec(CustomerAuditor::class.java,generalCriteria, pageSpec)
states.addAll(results.states);
pageNumber++
} while ((pageSpec.pageSize * pageSpec.pageNumber) <= results.totalStatesAvailable)
return states;
Output of this:
[
{
"state": {
"data": {
"linearId": {
"externalId": null,
"id": "d7b8331d-6a1a-408a-aff7-5c823e91c6e3"
}
},
"contract": "com.hsbc.contract.PSContract",
"encumbrance": null,
"constraint": {}
},
"ref": {
"txhash": {
"bytes": "FbMJYu2K1lrqHLK4rkhOogn5r/u7iAa26AobmrtWDRY=",
"size": 32,
"offset": 0
},
"index": 0
}
}
]
(i have removed the participants and notary tag as they were very big , i had 3 participants)
I always use this:
inline fun <reified T : LinearState> getLinearStateById(
linearId: UniqueIdentifier,
services: ServiceHub
): StateAndRef<T>? {
val query = QueryCriteria.LinearStateQueryCriteria(linearId = listOf(linearId))
return services.vaultService.queryBy<T>(query).states.singleOrNull()
}
I faced this. Just check if the Unconsumed State vault which you are trying to access is present Participants list. If it is not present than it will not be queried and thus list will always be empty. Hope this helps :)
In Java I did this way...!
#nithesh / #jayant let me know if it works..
UniqueIdentifier linearId = UniqueIdentifier.Companion.fromString(linearIdAsString);
QueryCriteria queryCriteria = new QueryCriteria.LinearStateQueryCriteria(
null, // List of Parties for the state
ImmutableList.of(linearId),
Vault.StateStatus.UNCONSUMED,
null // Set of State types
);
List<StateAndRef<YourState>> stateAndRefs = getServiceHub().getVaultService().queryBy(YourState.class, queryCriteria).getStates();
YourState yourState = stateAndRefs.get(0).getState().getData();

How do I access the error contents when using futures in Meteor?

I am using futures to make an async call to balanced payments. I want to catch errors and feed them back to the user so I can tell them why their payment failed.
Here is what I get on the server console. How can I parse out the errors[0].status, or errors[0].category_code from this error? I've tried to simply console.log(error[0].status);, but this does nothing.
I20140616-14:38:59.169(0)? "errors": [
I20140616-14:38:59.169(0)? {
I20140616-14:38:59.170(0)? "status": "Conflict",
I20140616-14:38:59.170(0)? "category_code": "card-not-validated",
I20140616-14:38:59.170(0)? "additional": null,
I20140616-14:38:59.170(0)? "status_code": 409,
I20140616-14:38:59.171(0)? "category_type": "logical",
I20140616-14:38:59.171(0)? "extras": {},
I20140616-14:38:59.171(0)? "request_id": "OHMf39d5030f56311e39cde02a
1fe53e539",
I20140616-14:38:59.171(0)? "description": "Card cannot be validated.
Your request id is OHMf39d5030f56311e39cde02a1fe53e539."
I20140616-14:38:59.172(0)? }
I20140616-14:38:59.172(0)? ]
Here is the future function I'm using.
var Future = Npm.require("fibers/future");
function extractFromPromise(promise) {
var fut = new Future();
promise.then(function (result) {
fut["return"](result);
}, function (error) {
fut["throw"](error);
fut.return(error.message);
});
return fut.wait();
}
I call this function from my code using something like this.
var customerData = extractFromPromise(balanced.marketplace.customers.create({
'name': customerInfo.fname + " " + customerInfo.lname,
"address": {
"city": customerInfo.city,
"state": customerInfo.region,
"line1": customerInfo.address_line1,
"line2": customerInfo.address_line2,
"postal_code": customerInfo.postal_code,
},
'email': customerInfo.email_address,
'phone': customerInfo.phone_number
}));
I had some help and got the answer. Hope this helps others. Here is the rewrite of the code I initially wrote.
The future code was both returning and throwing the error, so that was removed, the code was cleaned up a bit as well.
var Future = Npm.require("fibers/future");
function extractFromPromise(promise) {
var fut = new Future();
promise.then(function (result) {
fut.return(result);
}, function (error) {
console.log(error);
fut.throw(error);
});
return fut.wait();
}
And then the whole thing is wrapped in a try catch. I console log out the different parts of the message. Turned out that the JSON was stringified, so that had to be parsed first, then I could access the error like normal JSON data. And I've just learned that no errors will get back to the client unless you use the Meteor.error syntax first.
var customerData;
try {
customerData = extractFromPromise(balanced.marketplace.customers.create({
'name': customerInfo.fname + " " + customerInfo.lname,
"address": {
"city": customerInfo.city,
"state": customerInfo.region,
"line1": customerInfo.address_line1,
"line2": customerInfo.address_line2,
"postal_code": customerInfo.postal_code,
},
'email': customerInfo.email_address,
'phone': customerInfo.phone_number
}));
} catch (e) {
console.log(JSON.parse(e.message).errors[0].extras);
console.log(JSON.parse(e.message).errors[0].category_code);
var error = JSON.parse(e.message).errors[0];
throw new Meteor.Error(error.category_code, error.status_code, error.description, error.extras);
}

Resources