In my ember-data-using application I have an application serializer (mainly to take care of polymorphic relationships properly). However, its not used when I call toJSON() on a model instance, its not used -- rather the default JSONSerializer is used instead.
How can I customize the serializer used by toJSON()?
First of all i hope i understood properly your question...
Well, If you want to get the same result as in your ApplicationSerializer just call this.serialize() in your model.
If you want absolutely use the toJSON method without overwriting the default DS.Model of your whole app you can still make something like that :
App.CustomModel = DS.Model.extend({
toJSON: function(){
return this.serialize();
}
});
and then make all the concerned model extend this CustomModel
App.Color = App.CustomModel.extend({
name : DS.attr("string")
});
here is a working jsbin
In case you are looking to customize toJSON output for a particular model, you can do the following in your models/user.js file:
DS.Model.extend({
toJSON: function(options){
let json = this._super(options);
// Do something with json
return json;
}
});
Magic of Ember Object structure. In my case, I had to remove a property from toJSON response if it doesn't have value and this worked.
Related
I have a Controller (nestjs / routing-controllers) and I'm passing a GET request the following way: /collect?t=My-name
t is actually a full name which I can't change.
Bellow im injecting #QueryParams() data: CollectData, Im looking for a way (like java strong and .net) to tell the controller that fullName is actually t.
Something like
export interface CollectData{
#PropertyName('t')
fullName: string
}
I'm expecting fullName to represent the t variable.
#JsonController()
export class CollectController {
#Get('/collect')
collect(#QueryParams() data: CollectData){
return data.fullName;
}
}
You could use some sort of solution using the class-transformer library and the ValidationPipe given by Nest (it also does transformations!) and have your CollectionData class (use a class so that the data can be serialized after transpiling, interfaces go away in JavaScript) look like this:
// CollectData.ts
export class CollectData{
#Expose({ name: 'fullName' })
t: string
}
//Collect.controller.ts
#Controller() // Changed from JSONController to Controller
export class CollectController {
#Get('/collect')
collect(#Query(new ValidationPipe({ tranform: true }) data: CollectData){ //Changed from QueryParams to Query
return data.fullName;
}
}
OR in your main.ts add the app.useGlobalPipes(new ValidationPipe({ tranform: true }) to set the validation pipe to run against all your incoming requests
I'm new to unit / integration testing and I want to do an integration test of my controller which looks simplified like this:
// ItemsController.php
public function edit() {
// some edited item
$itemEntity
// some keywords
$keywordEntities = [keyword1, keyword2, ...]
// save item entity
if (!$this->Items->save($itemEntity)) {
// do some error handling
}
// add/replace item's keywords
if (!$this->Items->Keywords->replaceLinks($itemEntity, $keywordEntities)) {
// do some error handling
}
}
I have the models Items and Keywords where Items belongsToMany Keywords. I want to test the error handling parts of the controller. So I have to mock the save() and replaceLinks() methods that they will return false.
My integration test looks like this:
// ItemsControllerTest.php
public function testEdit() {
// mock save method
$model = $this->getMockForModel('Items', ['save']);
$model->expects($this->any())->method('save')->will($this->returnValue(false));
// call the edit method of the controller and do some assertions...
}
This is working fine for the save() method. But it is not working for the replaceLinks() method. Obviously because it is not part of the model.
I've also tried something like this:
$method = $this->getMockBuilder(BelongsToMany::class)
->setConstructorArgs([
'Keywords', [
'foreignKey' => 'item_id',
'targetForeignKey' => 'keyword_id',
'joinTable' => 'items_keywords'
]
])
->setMethods(['replaceLinks'])
->getMock();
$method->expects($this->any())->method('replaceLinks')->will($this->returnValue(false));
But this is also not working. Any hints for mocking the replaceLinks() method?
When doing controller tests, I usually try to mock as less as possible, personally if I want to test error handling in controllers, I try to trigger actual errors, for example by providing data that fails application/validation rules. If that is a viable option, then you might want to give it a try.
That being said, mocking the association's method should work the way as shown in your example, but you'd also need to replace the actual association object with your mock, because unlike models, associations do not have a global registry in which the mocks could be placed (that's what getMockForModel() will do for you) so that your application code would use them without further intervention.
Something like this should do it:
$KeywordsAssociationMock = $this
->getMockBuilder(BelongsToMany::class) /* ... */;
$associations = $this
->getTableLocator()
->get('Items')
->associations();
$associations->add('Keywords', $KeywordsAssociationMock);
This would modify the Items table object in the table registry, and replace (the association collection's add() acts more like a setter, ie it overwrites) its actual Keywords association with the mocked one. If you'd use that together with mocking Items, then you must ensure that the Items mock is created in beforehand, as otherwise the table retrieved in the above example would not be the mocked one!
I'd like to use a Method defined in the Mongoose Model after saving the retrieved Object to a Session. Its not working though. Is it normal that these methods get lost after storing it to the session?
Calling Method from Mongoose Model works fine:
Puppies.findOne({_id:123}).then(puppy => puppy.bark()) // WOOF WOOF
Storing Model in Session and calling method fails:
// First Request
Puppies.findOne({_id:123}).then(puppy => {
req.session.puppy = puppy
})
// Second Request somewhere else in the app
app.use(function(req,res,next){
req.session.puppy.bark() // req.session.puppy.bark is not a function
})
I've got the exact issue, but I believe what happens is that when you're storing the variable in session, it's being toObject()'d, causing it to become a simple JavaScript object, instead of remaining as an instance of Model. I've used Model.hydrate as a means of recreating this Model instance.
app.use(function(req,res,next){
let puppyModel = mongoose.model("puppy");
let puppy = puppyModel.hydrate(req.session.puppy);
puppy.bark() // Awooo
});
This essentially is creating a new Model and then filling it with all the relevant information so it acts a clone.
Because it is needing all the relevant information to make an update (including _id if you have it), I believe you may need to extend the toObject function to return getters/virtuals:
puppySchema.set('toObject', { getters: true, virtuals: true });
Else, when it attempts to save, and it's missing the _id field, it won't be able to save it.
I do hope someone else can provide a nicer method of doing this and/or explain why when storing it it has to be converted to an object and can't remain as an instance of Model.
I think what Ciaran Blewitt said was correct. Finally worked around it by just using mongoose statics:
puppy.model.js
schema.statics.bark(puppy) {
console.log(puppy.sound)
}
Storing Model in Session and getting desired effect via static:
// First Request, storing Puppy in Session
Puppy.findOne({_id:123}).then(puppy => {
req.session.puppy = puppy
})
// Second Request somewhere else in the app
app.use(function(req,res,next){
Puppy.bark(req.session.puppy) // WOOF WOOF
})
I struggled to create a unmarshaller that can make a Map[String, AnyRef] out of an httpEntity, So that the flowing route definition will work
path("cedt" / "processRow3") {
post {
entity(as[java.util.Map[String, AnyRef]]) {
rowobj => rowProcessorActor ! rowobj
complete {
"sent to backend actor"
}
}
}}
I read the akka document on marshalling and also some tutorial here http://malaw.ski/2016/04/10/hakk-the-planet-implementing-akka-http-marshallers/. But still I can't figure out how to get it done.
So My question is:
What are some of the components of an unmarshaller?
How to create those components and put them together?
It depends which format you want for serialized data.
For example, if you choose Json. You need to create implicit object with write and read methods for serializing and deserializing.
example:
implicit object MapJsonFormat extends JsonFormat[Map[String, AnyRef]] {
def write(m: Map[String, AnyRef]): JsValue =
def read(value: JsValue): Map[String, AnyRef] =
}
I want to bind a controller property that contains an ember-data object to a query string param. I'm using 1.6.0-beta.1+canary with the following in my controller.
export
default Ember.Controller.extend({
queryParams: ['project'],
project: null
});
I can't find a way to serialize/deserialize the ember-data object (project) to/from the url though. Is it possible yet?
I'm not sure why but it seems that the ember team don't want to support serialization of query-params. The best suggestion seems to be to do use a computed property like this:
App.MyController = Ember.ObjectController.extend({
queryParams: ['recordId']
recordId: null,
record: function(key, value) {
if (arguments.length > 1) {
//handle set by setting recordId
this.set('recordId', value.get('id');
}
return this.store.find('record', this.get('recordId'));
}.property('recordId')
});
It's workable but seems cludgy to say the least...