I'm trying to navigate between 2 pages in my application : ReplayView and ReplayDetailView.
The navigation works fine but I can't access the parameters in ReplayDetailViewModel.
Here is the code from ReplayViewModel :
public void ShowDetail()
{
navigationService.UriFor<ReplayDetailViewModel>()
.WithParam(x => x.progName, selectedProgram.titre)
.WithParam(x => x.progPrez, selectedProgram.animateur.prenom + ' ' + selectedProgram.animateur.nom)
.WithParam(x => x.progTime, selectedProgram.description)
.WithParam(x => x.progId, selectedProgram.id)
.Navigate();
}
I checked with BuildUri() and the query string is built correctly.
All the properties are defined in ReplayDetailViewModel :
private string name;
private string time;
private string prez;
private int id;
public string progName
{
get { return name; }
set
{
name = value;
NotifyOfPropertyChange(() => progName);
}
}
public string progPrez
{
get { return prez; }
set
{
prez = value;
NotifyOfPropertyChange(() => progPrez);
}
}
public string progTime
{
get { return time; }
set
{
time = value;
NotifyOfPropertyChange(() => progTime);
}
}
public int progId
{
get { return id; }
set
{
id = value;
NotifyOfPropertyChange(() => progId);
}
}
Both the ViewModels extends Screen and ReplayView is inside a pivot.
Related
I have the following Typescript code:
class Foo {
private _id: number;
private _desc: string;
constructor(id: number, desc: string) {
this._id = id;
this._desc = desc;
}
public get id(): number {
return this.id;
}
public set id(value: number) {
this._id = value;
}
public get desc():string {
return this.desc;
}
public set desc(value: string) {
this._desc = value;
}
}
let foo = new Foo(1, 'something');
I would like to get a string from a Typescript class, I mean with getter and setter. Then I should get the following string:
{"id":1,"desc":"something"}
According to this answer I can reach that adding the following method to the class:
public toJSONString(): string {
return JSON.stringify(this, Object.keys(this.constructor.prototype));
}
It works.
It doesn't work if the Typescript class contains any other sub class.
So if I have the following code:
class Foo {
private _id: number;
private _desc: string;
private _user: Bar;
constructor(id: number, desc: string, user: Bar) {
this._id = id;
this._desc = desc;
this._user = user;
}
public get id(): number {
return this._id;
}
public set id(value: number) {
this._id = value;
}
public get desc():string {
return this._desc;
}
public set desc(value: string) {
this._desc = value;
}
public get user(): Bar {
return this._user;
}
public set user(value: Bar) {
this._user = value;
}
public toJSONString(): string {
return JSON.stringify(this, Object.keys(this.constructor.prototype));
}
}
class Bar {
private _name: string;
private _surname: string;
constructor(name: string, surname: string) {
this._name = name;
this._surname = surname;
}
public get name(): string {
return this._name;
}
public set name(value: string) {
this._name = value;
}
public get surname():string {
return this._surname;
}
public set surname(value: string) {
this._surname = value;
}
}
let foo = new Foo(1, 'something', new Bar('foo', 'bar'));
If I use toJSONString method I get the following string:
{"id":1,"desc":"something","user":{}}
instead of this:
{"id":1,"desc":"something","user":{ "name": "foo", "surname": "bar"}}
So, how can I get a string from a Typescript class that has other sub classes?
(If you need here is the playground for the first code and here is the playground for the second code)
There are 2 things to keep in mind here:
When you define getters and setters they do not become instance methods once transpiled into Javascript, but they are added to the prototype using Object.defineProperty. This means you won't get them simply using JSON.stringify
Passing the replacer array to JSON.stringify and telling it to use only the prototype values does the job but it kinda doesn't work on nested objects. Truth is JSON.stringify will parse only the properties with that name no matter where it resides in the object structure.
For Example
let a = {
user: "Foo",
data: {
name: "Bar"
}
};
JSON.stringify(a, ["user", "data"]);
Will output {"user":"Foo","data":{}} because even though the nested object's key is data, the object itself does not have properties named user or data
But
let a = {
user: "Foo",
data: {
user: "Bar"
}
};
JSON.stringify(a, ["user", "data"]);
Will output {"user":"Foo","data":{"user":"Bar"}} because the nested object has a proprety called user, just like its parent
I reckon this behavior can be confusing but it's possible to implement a solution by creating a method that gets all the properties of all the objects you are interested in. I haven't found a way in Typescript to check whether a class implements a interface (or extends a class) so I had to work a bit with what I know it works even though it's not that "elegant".
abstract class Stringifyiable {
private isStringifyiable(value): boolean {
return value != null && (typeof value === 'object' || typeof value === 'function') && value['getJsonKeys'] && typeof value['getJsonKeys'] === 'function';
}
public getJsonKeys(): string[] {
let keys = Object.keys(this.constructor.prototype);
keys.forEach(key => {
if (this.isStringifyiable(this[key])) {
keys = keys.concat(this[key].getJsonKeys());
}
});
return keys;
}
public toJSONString(): string {
return JSON.stringify(this, this.getJsonKeys());
}
}
class Foo extends Stringifyiable {
private _id: number;
private _desc: string;
private _user: Bar;
constructor(id: number, desc: string, user: Bar) {
super();
this._id = id;
this._desc = desc;
this._user = user;
}
public get id(): number {
return this._id;
}
public set id(value: number) {
this._id = value;
}
public get desc():string {
return this._desc;
}
public set desc(value: string) {
this._desc = value;
}
public get user(): Bar {
return this._user;
}
public set user(value: Bar) {
this._user = value;
}
}
class Bar extends Stringifyiable {
private _name: string;
private _surname: string;
constructor(name: string, surname: string) {
super();
this._name = name;
this._surname = surname;
}
public get name(): string {
return this._name;
}
public set name(value: string) {
this._name = value;
}
public get surname():string {
return this._surname;
}
public set surname(value: string) {
this._surname = value;
}
}
let foo = new Foo(1, 'something', new Bar('foo', 'bar'));
//this will output {"id":1,"desc":"something","user":{"name":"foo","surname":"bar"}}
foo.toJSONString();
Be careful with cyclic references because it will go into an endless loop (I'm sure it can be fixed though).
I am working on a Java Spring boot application, with React JS as the front-end. In my react js project, on a form submit, I send data to the Spring API. For some reason, I am unable to map the javascript JSON array property to the java array property. All of the other String datatype properties match apart from the array. This is my example, on the react js front-end.
export function addBooking(bookings) {
return new Promise((resolve, reject) => {
axios.post(url, bookings)
.then((response) => {
resolve(response.data);
})
.catch((error) => {
reject(error);
});
});
}
Above is my react code which sends this JSON object, below.
{
"street": "someStreet",
"city": "somecity",
"contactNumber" : "0000",
“piecesData”: [
{
“id”: “111“,
“weight”: “22”,
“length”: “32”,
“width”: “23”,
“height”: “23”
“type”: “heavyLoad”
},
{
“id”: “111“,
“weight”: “22”,
“length”: “32”,
“width”: “23”,
“height”: “23”
“type”: “heavyLoad”
}
]
}
For some reason on the Spring server side the only properties that get mapped are street, city and contactNumber. However, the piecesData does not get mapped to it's corresponding java array property.
This is the Java model object:
public class Test implements Serializable{
public String city;
public String street;
public String contactNumber;
#OneToMany(
cascade = {CascadeType.ALL},
fetch = FetchType.EAGER
)
#JoinColumn(name = "booking_id", referencedColumnName = "booking_id")
public PieceData[] pieceData;
public String getCity() {
return City;
}
public void setCity(String city) {
City = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public PieceData[] getPieceData() {
return pieceData;
}
public void setPieceData(PieceData[] pieceData) {
this.pieceData = pieceData;
}
public String getContactNumber() {
return contactNumber;
}
public void setContactNumber(String contactNumber) {
contactNumber = contactNumber;
}
}
Once I am able to get all of this data then I wish to be able to save a Booking and it's pieceDatas array into the Database using JPA.
Below is my java PieceData object:
#Entity
#Table(name="pieceData")
public class PieceData implements Serializable{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String weight;
private String length;
private String width;
private Integer height;
private Integer booking_id;
public Integer getBooking_id() {
return this.booking_id;
}
public void setBooking_id(Integer booking_id) {
this.booking_id = booking_id;
}
public PieceData() {
}
public PieceData(Integer height, String length, String width, String weight) {
this.length = length;
this.width = width;
this.weight = weight;
this.height = height;
}
// Weight
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
// Length
public String getLength() {
return length;
}
public void setLength(String length) {
this.length = length;
}
// Width
public String getWidth() {
return width;
}
public void setWidth(String width) {
this.width = width;
}
// Height
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
}
I solved my answer by adding the json property annotation to the List pieceData type:
#JsonProperty(value = "piecesData")
private List<PieceData> piecesDatas;
My json request is as follows
{
"division":"XX",
"category":"XX",
"operation":"XXX",
"transactionId":"XX",
"trackNumber":"XXx",
"attentionReason":"",
"carNeedAttention":"",
"chargableDamage":"X",
"missingItems":"",
"offences":"N",
"outInAgentNumber":"XX",
"cList":{
{
"id":"230",
"elementCode":"XXX",
"value":"XXX",
"comment":"XX",
"label":"",
"uiComponent":"",
"featureType":""
}
},
"outInCprNumber":"XX",
"outInDate":"",
"outInDuration":"",
"outInFuel":"75",
"outInKm":"9999",
"outInRem1":"",
"outInRem2":"",
"outInRem3":"",
"userName":"XX",
"vehicleRetBy":""
}
I have a spring rest controller class
#Controller
#RequestMapping("/services")
public class CheckListController {
#RequestMapping(value = "/checkList", method = RequestMethod.POST, consumes="application/json",produces="application/json")
public ModelMap updateCheckList(#RequestBody CheckList checkList){
ModelMap modelMap = new ModelMap();
return modelMap;
}
}
CheckList class is as follows
import java.util.List;
public class CheckList {
String division;
String category;
String operation;
String transactionId;
String trackNumber;
String attentionReason;
String carNeedAttention;
String chargableDamage;
String missingItems;
String offences;
String outInAgentNumber;
List<MetaData> cList;
String outInCprNumber;
String outInDate;
String outInDuration;
String outInFuel;
String outInKm;
String outInRem1;
String outInRem2;
String outInRem3;
String userName;
String vehicleRetBy;
String updateMasterImage;
public String getDivision() {
return division;
}
public void setDivision(String division) {
this.division = division;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getOperation() {
return operation;
}
public void setOperation(String operation) {
this.operation = operation;
}
public String getTransactionId() {
return transactionId;
}
public void setTransactionId(String transactionId) {
this.transactionId = transactionId;
}
public String getTrackNumber() {
return trackNumber;
}
public void setTrackNumber(String trackNumber) {
this.trackNumber = trackNumber;
}
public String getAttentionReason() {
return attentionReason;
}
public void setAttentionReason(String attentionReason) {
this.attentionReason = attentionReason;
}
public String getCarNeedAttention() {
return carNeedAttention;
}
public void setCarNeedAttention(String carNeedAttention) {
this.carNeedAttention = carNeedAttention;
}
public String getChargableDamage() {
return chargableDamage;
}
public void setChargableDamage(String chargableDamage) {
this.chargableDamage = chargableDamage;
}
public String getMissingItems() {
return missingItems;
}
public void setMissingItems(String missingItems) {
this.missingItems = missingItems;
}
public String getOffences() {
return offences;
}
public void setOffences(String offences) {
this.offences = offences;
}
public List<MetaData> getcList() {
return cList;
}
public void setcList(List<MetaData> cList) {
this.cList = cList;
}
// public AccessoryList getAccessoryList() {
// return accessoryList;
// }
//
// public void setAccessoryList(AccessoryList accessoryList) {
// this.accessoryList = accessoryList;
// }
public String getOutInCprNumber() {
return outInCprNumber;
}
public void setOutInCprNumber(String outInCprNumber) {
this.outInCprNumber = outInCprNumber;
}
public String getOutInDate() {
return outInDate;
}
public void setOutInDate(String outInDate) {
this.outInDate = outInDate;
}
public String getOutInRem1() {
return outInRem1;
}
public void setOutInRem1(String outInRem1) {
this.outInRem1 = outInRem1;
}
public String getOutInRem2() {
return outInRem2;
}
public void setOutInRem2(String outInRem2) {
this.outInRem2 = outInRem2;
}
public String getOutInRem3() {
return outInRem3;
}
public void setOutInRem3(String outInRem3) {
this.outInRem3 = outInRem3;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getVehicleRetBy() {
return vehicleRetBy;
}
public void setVehicleRetBy(String vehicleRetBy) {
this.vehicleRetBy = vehicleRetBy;
}
public String getUpdateMasterImage() {
return updateMasterImage;
}
public void setUpdateMasterImage(String updateMasterImage) {
this.updateMasterImage = updateMasterImage;
}
public String getOutInAgentNumber() {
return outInAgentNumber;
}
public void setOutInAgentNumber(String outInAgentNumber) {
this.outInAgentNumber = outInAgentNumber;
}
public String getOutInDuration() {
return outInDuration;
}
public void setOutInDuration(String outInDuration) {
this.outInDuration = outInDuration;
}
public String getOutInFuel() {
return outInFuel;
}
public void setOutInFuel(String outInFuel) {
this.outInFuel = outInFuel;
}
public String getOutInKm() {
return outInKm;
}
public void setOutInKm(String outInKm) {
this.outInKm = outInKm;
}
}
MetaData is as folows
public class MetaData{
Integer id;
String label;
String uiComponent;
String featureType;
String value;
String comment;
String elementCode;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public void setId(int id)
{
this.id = id;
}
public String getLabel()
{
return label;
}
public void setLabel(String label)
{
this.label = label;
}
public String getUiComponent()
{
return uiComponent;
}
public void setUiComponent(String uiComponent)
{
this.uiComponent = uiComponent;
}
public String getFeatureType()
{
return featureType;
}
public void setFeatureType(String featureType)
{
this.featureType = featureType;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public String getElementCode() {
return elementCode;
}
public void setElementCode(String elementCode) {
this.elementCode = elementCode;
}
}
But when i submitting the json request it is giving 415 unsuporrted media type error.
What is wrong with this code. Do anybody havve the answer. Thanks in advance.
Nothing with the code. You just need to make sure that Your POST request has the HTTP Content-Type header set to "application/json".
If you use curl to POST the data you can use the following parameter to set the header value:
curl -H "Content-Type:application/json"
Add an Accept header too:
curl -H "Content-Type:application/json" -H "Accept:application/json"
I am using Dropwizard to deliver a RESTful service. The JSON I EXPECT looks like this:
{"featuredMerchants":
{"featuredMerchant":[
{"browseId":"v1_0_0_1112",
"merchantId":3902,
"priority":1,
"sourceId":"15"},
...,
{"browseId":"v1_0_0_1112",
"merchantId":456,
"priority":4,
"sourceId":"15"}]}}
But the JSON I am GETTING is this:
{"featuredMerchant":[
{"browseId":"v1_0_0_1112",
"merchantId":3902,
"priority":1,
"sourceId":"15"},
...,
{"browseId":"v1_0_0_1112",
"merchantId":456,
"priority":4,
"sourceId":"15"}]}
I have two classes. I have an ApiFeaturedMerchantGroup class that contains a list of ApiFeaturedMerchants.
#JsonRootName("featuredMerchants")
public class ApiFeaturedMerchantGroup {
private List<ApiFeaturedMerchant> apiFeaturedMerchants;
public ApiFeaturedMerchantGroup() {
}
#JsonProperty("featuredMerchant")
public List<ApiFeaturedMerchant> getApiFeaturedMerchants() { return apiFeaturedMerchants; }
public void setApiFeaturedMerchants(List<ApiFeaturedMerchant> apiFeaturedMerchants) { this.apiFeaturedMerchants = apiFeaturedMerchants; }
}
#JsonRootName("featuredMerchant")
public class ApiFeaturedMerchant {
private String browseId;
private int merchantId;
private Integer priority;
private String sourceId;
public ApiFeaturedMerchant() {
}
public String getBrowseId() { return browseId; }
public void setBrowseId(String browseId) { this.browseId = browseId; }
public int getMerchantId() { return merchantId; }
public void setMerchantId(int merchantId) { this.merchantId = merchantId; }
public Integer getPriority() { return priority; }
public void setPriority(Integer priority) { this.priority = priority; }
public String getSourceId() { return sourceId; }
public void setSourceId(String sourceId) { this.sourceId = sourceId; }
}
How do I get the extra level into my JSON, the "featuredMerchants" group that contains the individual "featuredMerchant" items? Do I have the wrong annotations, or am I missing one/some?
It's a setting on ObjectMapperFactory:
ObjectMapperFactory objectMapperFactory = new ObjectMapperFactory();
objectMapperFactory.enable(SerializationFeature.WRAP_ROOT_VALUE);
objectMapper = objectMapperFactory.build();
I have an Action class with 4 action methods.
All four action action methods use a json result.
Via logging statements and debugging, I have verified that if I call action method 1, action method 2 and 3 are also called. But not 4. Finally, action method 1 is called again and the json result is generated
If I change the result type of Action method 1 to the default dispatcher with a jsp location, only action method 1 is called. (this is the behavior I want with the json result)
Hope that makes sense.
Anyone have any ideas?
This question was asked here https://stackoverflow.com/questions/3767698/struts2-if-result-type-json-and-method-defined-then-all-methods-get-invoked
But there was no answer.
Please let me know if you need more information.
#ResultPath("/WEB-INF/jsp/dta/")
public class GroupEntityAction extends BaseAction {
/**
*
*/
private static final long serialVersionUID = 6750675222824235086L;
private static Logger log = Logger.getLogger(GroupEntityAction.class);
private List<EntityBusiness> theUnusedEntityBusinessList;
private String assignedEntities[];
private long groupId;
private long businessId;
private String parentMe;
private long rptYear;
private String ssoId;
private String isSubmitted;
private String delimGoLiveEmails;
private List<String> theEmailList;
#Action(value = "ajaxGetAvailableEntityList",
results = { #Result(name = "success", type = "json") }
,
interceptorRefs = { #InterceptorRef("dtaStack"),
#InterceptorRef(value = "dtaStack", params = { "appInterceptor.allowedRoles", "ADMIN" }) }
)
public String getEntityListsByBusiness() throws Exception {
if (rptYear == 0) {
return SUCCESS;
}
LookupService theSvc = new LookupService();
if (businessId != 0) {
setTheUnusedEntityBusinessList(theSvc.getAvailableEntityListBizExceptIds(rptYear, businessId, ssoId, assignedEntities));
} else {
setTheUnusedEntityBusinessList(theSvc.getAvailableEntityListParentMeExceptIds(rptYear, parentMe, ssoId, assignedEntities));
}
log.debug(theUnusedEntityBusinessList.size());
return SUCCESS;
}
#Action(value = "ajaxToggleGroupBusinessSubmitted",
results = { #Result(name = "success", type = "json") }
,
interceptorRefs = { #InterceptorRef("dtaStack") }
)
public String toggleGroupBusinessReview() {
try {
new ProformaService().toggleIsSubmitted(getCurrentUser().getSsoId(), groupId, rptYear, businessId);
} catch (SQLException e) {
log.error(e.getMessage());
return ERROR;
}
return SUCCESS;
}
#Action(value = "ajaxGetGoLiveEmailList",
results = { #Result(type = "json") }
,
interceptorRefs = { #InterceptorRef("dtaStack"),
#InterceptorRef(value = "dtaStack", params = { "appInterceptor.allowedRoles", "ADMIN" }) }
)
public String getGoLiveEmailList() {
try {
List<TaxUser> theUserList = new SecurityService().getAll();
List<String> theEmailList = new ArrayList<String>();
for (TaxUser theUser : theUserList) {
if ((!theUser.getRoles().contains("ADMIN")) && (theUser.getIsActive().equalsIgnoreCase("Y"))) {
if (!theEmailList.contains(theUser.getEmail())) {
theEmailList.add(theUser.getEmail());
}
}
}
setDelimGoLiveEmails(StringUtils.join(theEmailList.toArray(), "|"));
setTheEmailList(theEmailList);
} catch (SQLException e) {
log.error(e.getMessage());
return ERROR;
}
return SUCCESS;
}
#Action(value = "ajaxGetChaserEmailList",
results = { #Result(name = "success", type = "json") }
,
interceptorRefs = { #InterceptorRef("dtaStack"),
#InterceptorRef(value = "dtaStack", params = { "appInterceptor.allowedRoles", "ADMIN" }) }
)
public String getChaserEmailList() {
try {
List<String> theEmailList = new LookupService().getChaserEmailList();
setDelimGoLiveEmails(StringUtils.join(theEmailList.toArray(), "|"));
setTheEmailList(theEmailList);
} catch (SQLException e) {
log.error(e.getMessage());
return ERROR;
}
return SUCCESS;
}
public void setTheUnusedEntityBusinessList(
List<EntityBusiness> theUnusedEntityBusinessList) {
this.theUnusedEntityBusinessList = theUnusedEntityBusinessList;
}
public List<EntityBusiness> getTheUnusedEntityBusinessList() {
return theUnusedEntityBusinessList;
}
public void setAssignedEntities(String assignedEntities[]) {
this.assignedEntities = assignedEntities;
}
public String[] getAssignedEntities() {
return assignedEntities;
}
public void setGroupId(long groupId) {
this.groupId = groupId;
}
public long getGroupId() {
return groupId;
}
public void setBusinessId(long businessId) {
this.businessId = businessId;
}
public long getBusinessId() {
return businessId;
}
public void setParentMe(String parentMe) {
this.parentMe = parentMe;
}
public String getParentMe() {
return parentMe;
}
public void setRptYear(long rptYear) {
this.rptYear = rptYear;
}
public long getRptYear() {
return rptYear;
}
public void setSsoId(String ssoId) {
this.ssoId = ssoId;
}
public String getSsoId() {
return ssoId;
}
public void setIsSubmitted(String isSubmitted) {
this.isSubmitted = isSubmitted;
}
public String getIsSubmitted() {
return isSubmitted;
}
public void setDelimGoLiveEmails(String delimGoLiveEmails) {
this.delimGoLiveEmails = delimGoLiveEmails;
}
public String getDelimGoLiveEmails() {
return delimGoLiveEmails;
}
public void setTheEmailList(List<String> theEmailList) {
this.theEmailList = theEmailList;
}
public List<String> getTheEmailList() {
return theEmailList;
}
}
In this action class, I attempting to call ajaxGetGoLiveEmailList, and what I get is ajaxGetGoLiveEmailList called first, and then ajaxGetChaserEmailList, and then ajaxGetAvailableEntityList, and then ajaxGetGoLiveEmailList gets called again. ajaxToggleGroupBusinessSubmitted is skipped.
If I change the result annotation of ajaxGetGoLiveEmailList to
results={#Result(location="something.jsp")
, only ajaxGetGoLiveEmailList get called.
When I look at the config browser, all the action mapping are configured correctly, pointing to the correct method calls.
JSON plugin may be calling all your methods that start with "get" in an attempt to serialize them for output. Try renaming your methods to something else.