Webflow get Event Id in Controller - spring

Is there a way to get the _eventId parameter from the SWF RequestContext? Sometimes I need to use a bit of logic to decide where to transition to:
public String processATransition(RequestContext requestContext) {
String eventId = ?
if (eventId.equals("PREV")) {
if (currentViewState.equals("search")) {
return "searchParameters";
} else {
return "start";
}
}
}
Any help would be appreciated.

You can get it by:
String eventId = requestContext.getCurrentEvent().getId();

Related

Mono<Object> being returned instead of Mono<ResponseEntity> when mapping (Java 8)

Trying to practice reactive coding for an API but I'm struggling to understand what I'm doing wrong when using flatMap() and map() to cast to a ResponseEntity object. The error mentions that the code is returning a Mono<Object> and cant be cast/transformed into a Mono<ResponseEntity<>>.
Public Mono<ResponseEntity<?> deleteEndpoint(String someId) {
return db.existsById(someId).flatMap(exists -> {
if (!exists) return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
else {
Mono<Boolean> deletedStuff1 = someFunct();
Mono<Boolean> deletedStuff2 = anotherFunct();
Mono<Tuple2<Boolean, Boolean>> deletedStuff = Mono.zip(deletedStuff1, deletedStuff2);
return deletedStuff.then(Mono.just(ResponseEntity.status(NO_CONTENT).build());
}
});
}
All help is appreciated
From .flatMap() you must return Publisher, not actual object
In this if statement you return ResponseEntity instead of Mono<ResponseEntity>
So, just wrap it with Mono
if (!exists) {
return Mono.just(ResponseEntity.status(HttpStatus.BAD_REQUEST).build());
} else {
// ...

Java : set generic parameters for a method

I have a method that can take ResponseEntity as parameter.
private ResponseEntity<OfferRest> mappedOfferByImagesEnabled(
ResponseEntity<OfferRest> offerResponse) {
for (OfferDetailImageRest image :
offerResponse.getBody().getOfferDetail().getImages()) {
if (image.getDisabled()) {
return offerResponse;
}
}
return null;
}
I have the same method with another parameters: OfferEnity and I don't have need to call getBody() like the other one.
private OfferEntity mappedOfferByImagesEnabled(OfferEntity offerEntity) {
for (OfferDetailImageEntity image :
offerEntity.getOfferDetail().getImages()) {
if (image.getDisabled()) {
return offerEntity;
}
}
return null;
}
My idea is to have a method with one (generic) parameter. Basing on the settings instance I will run the convenient code.
My question, How can I do it?
You can create a method with OfferDetail parameter
public boolean isImageDisabled(OfferDetail offerdetail) {
return offerdetail.getImages().stream().anyMatch(Image::getDisabled));
}
And the use it
isImageDisabled(offerEntity.getOfferDetail());
isImageDisabled(offerResponse.getBody().getOfferDetail());

Cannot see why a controller method with 2 date parameters doesnt work

I have a really strange and frustrating issue
I have a controller with a standard Web Api Controller
[Route("Gateway/[Controller]/[action]")]
public class MyController: Controller
{
public MyController()
{
}
[ActionName("MyMethod")]
[System.Web.Http.HttpGet]
public async Task<IActionResult> MyMethodAsync(int numberParam, DateTime? startDate, DateTime? endDate)
{
var parameters = $"numberParam={numberParam}";
if (startDate != null)
{
parameters += $"&startDate={startDate.Value:O}";
}
if (endDate != null)
{
parameters += $"&endDate={endDate.Value:O}";
}
//My logic here - not relevant for question
return result;
}
}
When I call my method with the parameters
?numberParam=1&startDate=01/01/2018&endDate=31/01/2018
endDate comes through as null
Why is this?
There are no errors, I have no idea why the second parameter is being ignored
This applies regardless of the date format?
I dont need times
This occurs when using the full url eg http://mysite/GatewayController/MyMethod?numberParam=1&startDate=01/01/2018&endDate=31/01/2018
I also call this through a HttpClient, which doesnt work either
private static async Task<string> ProcessResponseAsync(HttpResponseMessage response)
{
var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
return responseText;
}
return "Error: " + response.StatusCode + " Content: " + responseText;
}
private static string GetUrl(string area, string method, string parameters)
{
if (!string.IsNullOrEmpty(parameters))
{
if (parameters[0] != '?')
{
parameters = $"?{parameters}";
}
}
var address = ConfigurationManager.AppSettings["GatewayUrl"];
var result = $"{address}/{area}/{method}{parameters}";
return result;
}
protected async Task<string> ExecuteRequestAsync(string area, string method, string parameters)
{
var url = GetUrl(area, method, parameters);
var response = await _httpClient.GetAsync(url).ConfigureAwait(false);
var result = await ProcessResponseAsync(response).ConfigureAwait(false);
return result;
}
Paul
Create the url without special charater "/", by replacing "/" with "-"
?numberParam=1&startDate=01-01-2018&endDate=31-01-2018
OR
Encode the special characters with,
https://www.w3schools.com/jsref/jsref_encodeURI.asp
https://www.w3schools.com/jsref/jsref_encodeURIComponent.asp

Vaadin 8 Datefield

How can i hide the immediate validation for the datefield in Vaadin 8 . I have the follwing code
dateField.setLocale(new Locale("fr", "CA"));
binder.forField(dateField).withValidator(new Validator<LocalDate>() {
#Override
public ValidationResult apply(LocalDate value, ValueContext context) {
if (LocalDate.now().equals(value)) {
return ValidationResult.ok();
} else {
return ValidationResult.error("the date is not the current date");
}
}
}).withValidationStatusHandler(new BindingValidationStatusHandler() {
#Override
public void statusChange(BindingValidationStatus<?> statusChange) {
if (statusChange.getResult().isPresent()) {
ValidationResult validationResult = statusChange.getResult().get();
if (validationResult.isError()) {
label.setCaption("the date is not the current date");
} else {
label.setCaption("the date IS the current date");
}
}
}
}).bind(CustomDate::getLocalDate, CustomDate::setLocalDate);
The result is however, that vaadin default validation (for example when the entered dateformat is not the expected format ) getting execued and my validation. I want to do the validation of the format expecitly in my validator. how to achieve that.
Maybe using setComponentError works for your use case. It should provide a way to override default error message.
For examples, see Handling Errors.
I did not try it but you can check if it works as described in the documentation (here):
DateField date = new DateField("My Date") {
#Override
protected Result<LocalDate> handleUnparsableDateString(
String dateString) {
try {
// try to parse with alternative format
LocalDate parsedAtServer = LocalDate.parse(dateString, DateTimeFormatter.ISO_DATE);
return Result.ok(parsedAtServer);
} catch (DateTimeParseException e) {
return Result.error("Bad date");
}
}
};
According to documentation, client-side validation can be hidden via CSS.

Refactoring Switch statement in my Controller

I'm currently working on a MVC.NET 3 application; I recently attended a course by "Uncle Bob" Martin which has inspired me (shamed me?) into taking a hard look at my current development practice, particularly my refactoring habits.
So: a number of my routes conform to:
{controller}/{action}/{type}
Where type typically determines the type of ActionResult to be returned, e.g:
public class ExportController
{
public ActionResult Generate(String type, String parameters)
{
switch (type)
{
case "csv":
//do something
case "html":
//do something else
case "json":
//do yet another thing
}
}
}
Has anyone successfully applied the "replace switch with polymorhism" refactoring to code like this? Is this even a good idea? Would be great to hear your experiences with this kind of refactoring.
Thanks in advance!
The way I am looking at it, this controller action is screaming for a custom action result:
public class MyActionResult : ActionResult
{
public object Model { get; private set; }
public MyActionResult(object model)
{
if (model == null)
{
throw new ArgumentNullException("Haven't you heard of view models???");
}
Model = model;
}
public override void ExecuteResult(ControllerContext context)
{
// TODO: You could also use the context.HttpContext.Request.ContentType
// instead of this type route parameter
var typeValue = context.Controller.ValueProvider.GetValue("type");
var type = typeValue != null ? typeValue.AttemptedValue : null;
if (type == null)
{
throw new ArgumentNullException("Please specify a type");
}
var response = context.HttpContext.Response;
if (string.Equals("json", type, StringComparison.OrdinalIgnoreCase))
{
var serializer = new JavaScriptSerializer();
response.ContentType = "text/json";
response.Write(serializer.Serialize(Model));
}
else if (string.Equals("xml", type, StringComparison.OrdinalIgnoreCase))
{
var serializer = new XmlSerializer(Model.GetType());
response.ContentType = "text/xml";
serializer.Serialize(response.Output, Model);
}
else if (string.Equals("csv", type, StringComparison.OrdinalIgnoreCase))
{
// TODO:
}
else
{
throw new NotImplementedException(
string.Format(
"Sorry but \"{0}\" is not a supported. Try again later",
type
)
);
}
}
}
and then:
public ActionResult Generate(string parameters)
{
MyViewModel model = _repository.GetMeTheModel(parameters);
return new MyActionResult(model);
}
A controller should not care about how to serialize the data. That's not his responsibility. A controller shouldn't be doing any plumbing like this. He should focus on fetching domain models, mapping them to view models and passing those view models to view results.
If you wanted to "replace switch with polymorphism" in this case, you could create three overloaded Generate() ActionResult methods. Using custom model binding, make the Type parameter a strongly-typed enum called DataFormat (or whatever.) Then you'd have:
public ActionResult Generate(DataFormat.CSV, String parameters)
{
}
public ActionResult Generate(DataFormat.HTML, String parameters)
{
}
public ActionResult Generate(DataFormat.JSON, String parameters)
{
}
Once you get to this point, you can refactor further to get the repetition out of your Controller.

Resources