Simple example for mapping attributes #279
-
First, thanks for this package. I know I need it because i don't want to have all kind of coding lines with mappings in my Controller. But, i don't know how to start. I have a incoming post request from an Excel file. Unfortunatly, I can't change how the post is made by VBA. The names of the attributes are not equal to the attribute names of my Model. So, I receive a JSON post which I am trying to map to my model, using Valinor. For the sake of simplicity, lets say I receive this JSON :
Now, my model is called "Stock" and has 2 attributes: "name" and "ticker". I have another model called StockTransactions which has a 1:n relation with Stock (one stock can have many transactions). I created a StockData class:
In my api controller I have this method:
Nothing is happening. I read something about mapping the attributes, but I want the mapping to be done in the StockData class and not in the controller. How can I achieve this? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
Hi @TutanRamon, I have several suggestion to make: It seems that the request arguments describe a list of (new \CuyZ\Valinor\MapperBuilder())
->mapper()
->map('list<' . StockData::class . '>', /* … */); Note that it would also work with an array. You can find the list of available types in the documentation. Next, the request object seems to be able to provide an array of raw data, you probably don't need to use the (new \CuyZ\Valinor\MapperBuilder())
->mapper()
->map('list<' . StockData::class . '>', $request->all()); Because the source contains superfluous keys (more data than actually needed), you need to activate an option in the mapper builder: (new \CuyZ\Valinor\MapperBuilder())
->allowSuperfluousKeys()
->mapper()
->map('list<' . StockData::class . '>', $request->all()); The keys in the input do not match the properties of your DTO, so you need to tell the mapper about it. This is done by using a custom source like below. More information can be found in the documentation. $source = $source = Source::iterable($request->all())->map([
'*.Company Name' => 'Naam'
]);
(new \CuyZ\Valinor\MapperBuilder())
->allowSuperfluousKeys()
->mapper()
->map('list<' . StockData::class . '>', $source); Finally, you obviously need to handle the error. I can't be of any help because it will really depend on how you can/need to manage it in your application, but you can find more information about this topic in the documentation. Hope this helps. |
Beta Was this translation helpful? Give feedback.
-
Ok, I am a bit further. However, when I look at the JSON that is being sent, I see basiscally a double nested array. Each "stock" holds an array called "Transactions". Within this array, there is an array of Transaction. The JSON looks like this:
I am trying to get to the level of transactions. I got it working, but the output is not what I want it to be.
My Controller:
|
Beta Was this translation helpful? Give feedback.
Hi @TutanRamon, I have several suggestion to make:
It seems that the request arguments describe a list of
StockData
, so it looks like you need to map not to the class directly, rather a list of it:Note that it would also work with an array. You can find the list of available types in the documentation.
Next, the request object seems to be able to provide an array of raw data, you probably don't need to use the
JsonSource
. You probably can do something like the example below, as long as you provide an iterable to the mapper.