I'm also looking for Mapping reference Object property using JMapper. For example.
class Person { int id; Address addr; }
class Address {String city;}
I want to map 'city' from Address class to my Desitnation class instead of mapping 'addr' property to Address type.
class Destination {
#JMap int id;
#JMap
Sting city;
}
I used #JMap("city") or #JMap("addr.city"), but nothing work. Even I don't see any documentation regarding that. Any help is appreciated.
Nested Mapping is available with the convention ${field.field}.
For more information visit the wiki page.
Related
I am beginner in dart language.
So i created this class ..
class X{
String name;
int age;
// X(this.name,this.age);
X(name,age);
}
In this code the short form ctor X(name,age) gives error that name and age must be initilized but the ctor X(this.name,this.age) doesnt give such error.
In ctor X(this.name,this.age) compiler know that name and age will surely be initilized..
but in ctor X(name,age) why compiler cannot do that....(isn't it obvious that name and this.name is same thing).
please elaborate....
In Dart, if you don't specify any type, the language will assume you mean dynamic in this case.
So what your code is actually doing is:
class X{
String name;
int age;
X(dynamic name, dynamic age);
}
The problem then becomes that we don't assign these parameters to anything in the class since the name in the constructor would be a different name than the name in the class definition.
The analyzer would therefore complain about name and age not being provided a value since both fields are defined with non-nullable types and can therefore not be null (which is the default value for any variable in Dart regardless of its type).
The this.name and this.age is a shortcut to the following code:
class X{
String name;
int age;
X(String name, int age) : name = name, age = age;
}
The name = name works because we are not allowed to set the parameter to some other value in the initializer part of the constructor. So Dart can assume that the first name must mean the class variable while the second name means the parameter, since the parameter is the one closest in scope.
I've been following my new journey into learning Solidity. Now I'm into a structs + Data locations course, and I came to a situation when I didn't use the exact same example as the instructor did, both works. I would like to know which one is technically more correct.
Concerning the way the instructor did, I understand that if that data variable already exists, filled with data, and we're using it on a Storage, that would be understandable but for the Memory case, I still don't get the meaning of it.
Here are the two exmples:
Mine:
struct PERSON {
uint256 id;
string name;
}
PERSON public personList;
function updateNewPerson(uint256 _index, string memory _name) public {
PERSON memory newUpdatedPerson;
newUpdatedPerson.name = _name;
personList[_index] = newUpdatedPerson;
}
Instructor code:
struct PERSON {
uint256 id;
string name;
}
PERSON public personList;
function updateNewPerson(uint256 _index, string memory _name) public {
PERSON memory newUpdatedPerson = personList[index];
newUpdatedPerson.name = _name;
personList[_index] = newUpdatedPerson;
}
This is the same example with Storage data location I'm reffering to:
function updateStoragePerson(uint256 _index, string memory _name) public {
PERSON storage newUpdatedPerson = personList[_index];
newUpdatedPerson.name = _name;
}
I'm trying to figure out the is there's any difference there and i think I'm starting to uderstand it, and please correct me if I'm wrong.
So in my example I'm basically just passing the new user insert new value, which is in this case _name, then when giving it back to the array handing it to its position through the index array.
When on the instructor example, he's passing through the array index case content, which is id and name, then insering the new name value from the function before passing back the data to the array, and in this case id and _name are identical.
What I can see is that, in your code, when you create a newUpdatedPerson, you are creating an empty variable of type PERSON, and then you only fill it with the name, whereas your instructor takes the original value from a person which already exists and then updates its value. This will result in your newUpdatedPerson in your personList to update its name but its id will become empty.
The newUpdatedPerson will be stored in personList as copies from storage to local storage actually copy a reference to the storage so any update on newUpdatedPerson will result in an update to personList.
Assignments from storage to a local storage variable also only assign a reference.
I hope you find this information helpful :)
State variables are storage by default (values are stored in the blockchain).
Local variables in functions are memory by default (values are stored temporarily in memory).
Structs are storage by default (values are stored in the blockchain).
I explained how memory and storage type behave differently on this stackoverflow post
As far I been to doc's and tutorials I got to know we need to use underscore to define properties or methods but from by below code I can still access it.
void main() {
User d = new User('John Doe', 5);
print(d._name);
}
class User {
String _name;
int age;
User(this._name, this.age);
String respectedName(nname) {
return 'Mr.$nname';
}
}
I am not sure that I understand how things works in Dart, please help.
There is smiler question answered here, but that's still not much of a helpful answer to me.
Private properties/methods in dart are accessible for the whole file and not accessible from other files.
This can be combined with part/part of keyword to treat two+ files as one.
I tried to change the standard 'id' in grails:
calls Book {
String id
String title
static mapping {
id generator:'assigned'
}
}
unfortunately, I soon noticed that this breaks my bootstrap. Instead of
new Book (id:'some ISBN', title:'great book').save(flush:true, failOnError:true)
I had to use
def b = new Book(title:'great book')
b.id = 'some ISBN'
b.save(flush:true, failOnError:true)
otherwise I get an 'ids for this class must be manually assigned before calling save()' error.
but that's ok so far.
I then encountered the same problem in the save action of my bookController. But this time, the workaround didn't do the trick.
Any suggestions?
I known, I can rename the id, but then I will have to change all scaffolded views...
That's a feature of databinding. You don't want submitted data to be able to change managed fields like id and version, so the Map constructor that you're using binds all available properties except those two (it also ignores any value for class, metaClass, and a few others).
So there's a bit of a mismatch here since the value isn't managed by Hibernate/GORM but by you. As you saw the workaround is that you need to create the object in two steps instead of just one.
I can't replicate this problem (used Grails 2.0.RC1). I think it might be as simple as a missing equal sign on your static mapping = { (you just have static mapping {)
Here's the code for a domain object:
class Book {
String id
String name
static mapping = {
id generator:'assigned'
}
}
And inside BootStrap.groovy:
def init = { servletContext ->
new Book(name:"test",id:"123abc").save(failOnError:true)
}
And it works fine for me. I see the id as 123abc.
You need to set the bindable constraint to true for your id prop, e.g.
class Employee {
Long id
String name
static constraints = {
id bindable: true
}
}
My problem is hydrating a Viewmodel from a Linq2Sql object that has been returned from the database. We have done this in a few areas and have a nice layered pattern worked up for it but the latest item calls for some enums to be used and this has caused headaches all round. Currently we pull back from the database then use Automapper to hydrate (or flatten) into our Viewmodels but having the enums in the model seems to be causing issues with Automapper. I've tried to create custom resovlers which have sufficed for all my other mapping requirements but it doesn't work in this instance.
A sample of the code looks like:
public class CustomerBillingTabView{
public string PaymentMethod {get; set;}
...other details
}
public class BillingViewModel{
public PaymentMethodType PaymentMethod {get; set;}
...other details
}
public enum PaymentMethodType {
Invoice, DirectDebit, CreditCard, Other
}
public class PaymentMethodTypeResolver : ValueResolver<CustomerBillingTabView, PaymentMethodType>
{
protected override PaymentMethodType ResolveCore(CustomerBillingTabView source)
{
if (string.IsNullOrWhiteSpace(source.PaymentMethod))
{
source.PaymentMethod = source.PaymentMethod.Replace(" ", "");
return (PaymentMethodType)Enum.Parse(typeof(PaymentMethodType), source.PaymentMethod, true);
}
return PaymentMethodType.Other;
}
}
CreateMap<CustomerBillingTabView, CustomerBillingViewModel>()
.ForMember(c => c.CollectionMethod, opt => opt.ResolveUsing<PaymentMethodTypeResolver>())
I get the following error
[ArgumentException: Type provided must be an Enum.
Parameter name: enumType]
System.Enum.TryParseEnum(Type enumType, String value, Boolean ignoreCase, EnumResult& parseResult) +9626766
System.Enum.Parse(Type enumType, String value, Boolean ignoreCase) +80
AutoMapper.Mappers.EnumMapper.Map(ResolutionContext context, IMappingEngineRunner mapper) +231
AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context) +720
I'd like to stick with Automapper for all of our mapping actions but I've seen a lot of people say that it doesn't do this type of mappings so I'm starting to wonder if I'm using it in the wrong way? Also, I've seen a few mentions of ValueInjecter - is this an alternative to Automapper, or will it be useful to just plug the holes in Automapper for the hydration of models and use Automapper for flattening?
Yes I could just use a string in my ViewModel, but I'm not a fan of magic strings, and this particular item is used by helpers to perform some logic in a number of places.
This is an issue with the AutoMapper documentation. If you download the AutoMapper source there are examples in there. The code you want will look like this:
public class PaymentMethodTypeResolver : ValueResolver<CustomerBillingTabView, PaymentMethodType>
{
protected override PaymentMethodType ResolveCore(CustomerBillingTabView source)
{
string paymentMethod = source.Context.SourceValue as string;
if (string.IsNullOrWhiteSpace(paymentMethod))
{
paymentMethod = paymentMethod.Replace(" ", "");
return source.New((PaymentMethodType)Enum.Parse(typeof(PaymentMethodType), paymentMethod, true));
}
return source.New(PaymentMethodType.Other);
}
}
here's a solution with the ValueInjecter:
since you already solved the problem I'm just going to point you to something similar:
AutoMapper strings to enum descriptions
in this question the requirements were a bit more than just doing from string to enum, but it includes this conversion also
about the ValueInjecter being an alternative: yes, it does stuff more generic no configuration for every little thing required, and build whatever convention you can imagine