I want to create a .ts file which should contain my data model. Each data model maps to a JSON I'll either send or receive from the server. For eg. for user profile, the Json is
{
"firstname" : "d",
"lastname" : "d",
"email" : "dd",
"password" : "d"
}
For above, I want to create a class as follows
export class UserProfile {
constructor (public firstname:string,
public lastname:string,
public email:string,
public password:string){}
}
Another JSON which the server might send is
{
result:"success"
addition-info:"something"
}
The class for above is
export class Result{
constructor (public result:string,
public additionalInfo:string){}
}
Is there a best practice in Angular on how to create files for data models. Could I create a single .ts file say BackendApiModels.ts which should store all the classes or shall I create one .ts file for each data model? I don't even know if it is possible to create a .ts file which can contain multiple classes, eg
BackendApi.ts
export class UserProfile {
constructor (public firstname:string,
public lastname:string,
public email:string,
public password:string){}
}
export class Result{
constructor (public result:string,
public additionalInfo:string){}
}
Is is possible to create a file like above in Angular (multiple classes and the name of the classes do not match the filename)?
It is entirely possible and valid to export several model classes or interfaces from the same .ts file...
export class Attachment {
id: number;
name: string;
constructor(attachment) {
this.id = attachment.id;
this.name = attachment.name;
}
}
export class Permissions {
draftable: boolean;
completable: boolean;
constructor(perms) {
this.draftable = perms.draftable;
this.completable = perms.completable;
}
}
Related
I am working on localization and I want to create a global resource file for all the strings for all views. I created resource files for model, controller and view but I need a global type of resource file that can store key value pair for Views. I don't don't know how to achieve this and where should I store my global resource file? Should I store it in models or services or in controllers?
in your Resources folder add the following files: (do your necessary imports of the code needed)
public class SharedViewLocalizer : ISharedViewLocalizer
{
private readonly IStringLocalizer localizer;
public SharedViewLocalizer(IStringLocalizerFactory factory)
{
var type = typeof(SharedResource);
var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
this.localizer = factory.Create("SharedResource", assemblyName.Name);
}
public LocalizedString this[string key] => this.localizer[key];
public LocalizedString GetLocalizedString(string key)
{
return this.localizer[key];
}
}
public interface ISharedViewLocalizer
{
public LocalizedString this[string key]
{
get;
}
LocalizedString GetLocalizedString(string key);
}
public class SharedResource
{
}
add a file called SharedResource.en-US.resx in the resource folder
in your cshtml:
#using yourdirectory.Resources
#inject ISharedViewLocalizer Localizer
also don't forget to dependency inject
services.AddTransient<ISharedViewLocalizer, SharedViewLocalizer>();
If you have done all this in your cshtml you can then do:
Localizer["something"]
which will write the translation on the html page.
someone posted this: https://medium.com/#flouss/asp-net-core-localization-one-resx-to-rule-them-all-de5c07692fa4
special thanks to him.
I am writing a Spring Boot app (RESTful webservice) that uses Jackson for serialization. I have the following data models that will be sent back and forth between the service and its HTTP clients (hence these will be serialized/deserialized to/from JSON):
public abstract class BaseEntity {
#JsonIgnore
private Long id;
private UUID refId;
// Getters, setters, ctors, etc.
}
public abstract class BaseLookup extends BaseEntity {
private String name;
private String label;
private String description;
// Getters, setters, ctors, etc.
}
public class State extends BaseLookup {
private String abbrev; // "VT", "FL", etc.
// Getters, setters, ctors, etc.
}
public class Contact extends BaseEntity {
private String givenName;
private String surname;
private State state;
// Getters, setters, ctors, etc.
}
public class Account extends BaseEntity {
private Contact contact;
private String code;
// lots of other fields that will be generated server-side
// Getters, setters, ctors, etc.
}
Thus there will be some endpoints for CRUDding Accounts, others for CRUDding Contacts, etc. For instance, the AccountController will expose endpoints for CRUDding Account instances:
#RestController
#RequestMapping(value = "/accounts")
public class AccountController {
#RequestMapping(method = RequestMethod.POST)
public void createAccount(#RequestBody Account account) {
// Do stuff and persist the account to the DB
}
}
I want to simplify the JSON that HTTP clients must craft in order to create new Account, Contact, etc. instances. At the same time there are fields on those data models that I do not want exposed to the client-side. Things like the BaseEntity#id (which is the PK of the entity in the DB). Or for instance, in the case of State, I just want the client-side to know about (and use) the abbrev field, etc. I don't want them to ever see the other BaseLookup fields or even know about them.
Hence, my end goal is to allow the client to POST the following JSON, and have a custom Jackson deserializer convert that JSON into an Account instance:
{
"contact" : {
"givenName" : "Him",
"surname" : "Himself",
"state" : "NY"
},
"code" : "12345"
}
So you see, like I stated above, this JSON accomplishes several things:
The client-side doesn't provide a BaseEntity#id or BaseEntity#refId when POSTing to create a new instance
For the contact.state field, which is a BaseLookup with several fields (id, refId, name, label, description, abbrev), the user only has to provide the abbrev field, and the deserializer is expected to figure out which State the client is referring to
The Account class actually has many other fields that are inferred/generated server-side; the client doesn't need to know about them in order to create an Account instance
The JSON above is a simplified form of what we would get if we serialized an Account with Jackson's default behavior; this is to make things easier on the client-side and even more secure on the server-side (not exposing PKs, etc.)
The important thing to note here is that the JSON sent to this controller for the contact field is identical to the JSON that will be POSTed to a ContactController for creating new Contact instances.
Here's the problem:
public class AccountDeserializer extends StdDeserializer<Account> {
public AccountDeserializer() {
this(null);
}
public AccountDeserializer(Class<Account> accClazz) {
super(accClazz);
}
#Override
public Account deserialize(JsonParser jsonParser, DeserializationContext dCtx)
throws IOException, JsonProcessingException {
JsonNode jsonNode = jsonParser.codec.readTree(jsonParser)
Contact contact = ??? // TODO: How to invoke ContactDeserializer here?
String accountCode = node.get("code").asText();
// Generate lots of other Account field values here...
Account account = new Account(contact, accountCode, /* other fields here */);
return account;
}
}
Since I will also have a ContactController (for CRUDding Contact instances irrespective of an associated Account), and because I have similar desires to hide Contact fields from the client-side as well as to simplify the JSON coming into this ContactController#createContact endpoint, I will also need a ContactDeserializer in addition to this AccountDeserializer...
public class ContactDeserializer extends StdDeserializer<Contact> {
// ...etc.
}
This ContactDeserializer will be responsible for converting JSON into Contact instances. But since Account instances also contain Contact instances, and because the "contact JSON" inside the outer "account JSON" will be the same as any JSON that the client sends to any of the "contact endpoints", I'd like to invoke the ContactDeserializer from inside the AccountDeserializer somehow.
That way, when the ContactController receives "contact JSON" to create a new Contact instance, the ContactDeserializer is engaged to get the job done. And, if the AccountController receives "account JSON" to create a new Account instance, then the AccountDeserializer is engaged to get that job done...and it uses the ContactDeserialzer to handle the deserialization of the account JSON's internal contact field as well.
Can this be done?! Can one Jackson deserializer reuse other deserializers inside of it? If so, how? If not, then what's the solution here?!
You can invoke ContactDeserializer by calling the treeToValue method of ObjectCodec. Jackson will automatically pick up the ContactDeserializer for you if you've registered it on your ObjectMapper.
public class AccountDeserializer extends JsonDeserializer<Account> {
#Override
public Account deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
JsonNode node = p.readValueAsTree();
JsonNode contactNode = node.get("contact");
Contact contact = null;
if (contactNode != null) {
contact = p.getCodec().treeToValue(contactNode, Contact.class);
}
return new Account(contact, /* account properties */);
}
}
Edit
If you want to add your deserializers to existing mapper which is created by Spring Boot, you can autowire it in one of your configuration classes and customize as you like.
#Configuration
public class ObjectMapperConfiguration {
#Autowired
public void configureObjectMapper(ObjectMapper mapper) {
SimpleModule module = new SimpleModule()
.addDeserializer(Account.class, new AccountDeserializer())
.addDeserializer(Contact.class, new ContactDeserializer());
mapper.registerModule(module);
}
}
I'm switching a Zend Framework application from mono-user to multi-user.
What is the best approach to include the user scope in the controllers ?
One way would be to add the user id in each methods in every controllers:
/application/controllers/IndexController.php
...
public function indexAction() {
$params['user_id'] = Zend_Auth::getInstance()->getIdentity()->id;
$listHelper->readItems($params);
}
...
An other one would be to create a new User model and fetch his items :
/application/controllers/IndexController.php
...
public function indexAction() {
$userModel = new application_models_user();
$userModel->find(Zend_Auth::getInstance()->getIdentity()->id);
$userModel->readItems();
}
...
I'm wondering what's the best approach that would allow me to write minimal code and if you have another idea to "automagically" add the user scope (db scope, plugin...).
Create an abstract class by extending Zend_Controller_Action
abstract class My_Controller_Action extends Zend_Controller_Action {
private $userModel;
public function getUserModel() {
if(is_null($this->userModel)) $this->userModel = new application_models_user();
return $this->userModel;
}
public function getUserId() {
return $this->getUserModel()->find(Zend_Auth::getInstance()->getIdentity()->id);
}
}
Now use this class as base class for your controllers.
I was wondering how to get a variable equivalent from another .cs file with "using" statement.
Like
using (namespace here)
Output(A, 8);
and the file with (namespace here) would have
A = 3
would I be able to directly refer to the variable, or would I need to locate it some other way?
If you just want to define a bunch of constant values in one location that can be used elsewhere this is the standard pattern you would follow:
namespace MyNameSpace
{
public static class Constants
{
public const int MyFavoriteNumber = 3;
}
}
Then somewhere else you can have:
using MyNameSpace;
namespace MyOtherNameSpace
{
public class MyClass
{
public void Method()
{
Console.WriteLine(Constants.MyFavoriteNumber);
}
}
}
You can't dynamically change the scope of a code like that. What an identifier is, is determined at compile time, so you can't change what it means at runtime.
Make a class or an interface that specifies what it is that you want to use from the different files, then inherit the class or implement the interface to make different implementations in different files. When you use one of the implementations you get the values from that file.
Example:
public interface ICommon {
int A { get; }
}
public class File1 : ICommon {
public int A { get { return 42; } }
}
public class File2 : ICommon {
private int _value = 1;
public int A { get { return _value; } }
}
Now you can use different objects:
ICommon x;
if (something) {
x = new File1();
} else {
x = new File2();
}
Output(x.A, 8);
.CS files contains classes, not variables. If the .CS file contains a class that has a static property A you would just reference that static property:
Output(ClassName.A, 8);
Otherwise you need to provide more context as to what you have and what you're trying to do.
I am having a bit of trouble understanding how I will design a class.
I want to be able to get n amount of System fields out onto a report alongside custom fields.
I want a simple method on an interface called:
ICollection<Field> GetFieldDefinitions();
Internally this should get all the fields that I need to show on the report.
A second method will return field and their values too:
ICollection<Field> GetFieldDefinitionsWithValues(T src);
T is the source of where the information for each field will be populated from, e.g. if I pass in Company, the field definition if it contains CompanyName, I will do a lookup on the Company table and retrieve the info and add it to the field.
public Class SystemFieldCompany
{
IDictionary<string,Field> list;
private readonly ValidationEngine _val;
public SystemFieldCompany(ValidationEngine val)
{
_val = val;
list = new Dictionary<string,Field>();
}
public ICollection<Field> GetFields()
{
list.add("id",new Field{name = "id", value = "5"});
list.add("nameofcompany",new Field{name = "nameofcompany", value = "super guys"});
return list.Values;
}
//pass in model object with values on it, set up fields, then pass back all fields
ICollection<Field> GetFieldsWithValues(T object);
}
Should this class above be a concrete class?
e.g. var fields = new FieldClass().GetFields();
or should I use composition? How can I do this via an interface?
Abstract Class is what your after
public abstract class FieldBase
{
ICollection<Field> _data=new List<Field>();
abstract void DoValidationOrSomething();
ICollection<Field> virtual GetFields() //perform validation internally - return back the object
{
DoValidationOrSomething();
return _data;
}
T virtual UpdateFields(ICollection<Field> fields); //pass in model object with values on it, set
{
_data.Clear();
_data.AddRange(fields);
}
up fields, then pass back all fields
ICollection<Field> virtual GetFieldsWithValues(T object)
{
return _data.Where(f=>f.Name=T);
}
}
then in your concrete
public class SomeTable:FieldBase
{
public void DoValidationOrSomething()
{
//per class validation here
}
}