Reputation: 4792
I am working in a web application which has a server powered by ASP.NET Core MVC and the frontend is an Angular 5.0 Single Page Application using TypeScript.
In the client I have a page with a form and some <select>
input controls. My design challenge here is that the choices in the <select>
should be restricted to what values the Web API in my .NET Core expect.
Since the server and the client application are part of the same Visual Studio solution I wanted to try to minimize breaking changes in the Web API. One way I thought I might be able to do this is to have the client-side forms and inputs be somewhat dumb and to request from the server the valid values to populate the <select>
controls with. This way I don't have to duplicate logic in the client and the server (For instance, if I defined an Enum in C# and again in TypeScript). There's a few down sides to this though that I can think of (like if I wanted to toggle visibility of other form fields based on the <select>
value, I would have to hard-code logic in the client which makes assumptions about values.
Is this a good idea? What kind of other solutions could I use?
Upvotes: 10
Views: 1396
Reputation: 176
You can can use FormGroup from @angular/forms. You should create a function of initForm(), and in that function call another function that sends api request to get the data to populate your form from server. And you can call that function (change) event of your <select>
. Something like this:
initForm(selectedOption?) {
this.getFormData(selectedOption);
userForm = new FormGroup({
name: new FormControl(this.formData.name),
age: new FormControl(this.formData.age)
});
}
getFormData(selectedOption?) {
this.http('url')
.map(res => res.json())
.subscribe(data => {
this.formData = data;
});
}
HTML:
<select #selectOptions (change)="initForm(selectOptions.value)">
<option *ngFor="let option of formData.choices"></option>
</select>
Upvotes: 0
Reputation: 334
The best way to implement the latest framework features in order to solve your problems would come from Okan Aslankan's answer. It might seem a bit complicated right now, but I am sure you would be able to find documentation on it.
If at all you want to try something else, I have one more implementation idea which might seem simpler. Make a few rest API services in your C# project which will help you populate your <select>
tag. Make similar services in angular project which would call these APIs to get the values as and when needed. If you want to modify the values in your <select>
according to some previous form field values, then use Ajax scripts to call your APIs instead of angular services and get the data in real time and render it on the HTML.
Both of these can be used to solve different type of scenarios in your whole solution. So take a pick and I am sure any one of them would help you solve it.
Upvotes: 0
Reputation: 3116
IF you are using ssr you can pass data to angular application from pre-rendering module.
In startup.cs
app.UseSpa(spa =>
{
...
spa.UseSpaPrerendering(options =>
{
...
options.SupplyData = (context, data) =>
{
// Your c# array
data["selectValues"] = ["YOUR","ARRAY","OF","VALUES"];
// some other data
};
});
});
Then in your main.server.ts file you can inject the array into angualar app.
import { createServerRenderer } from 'aspnet-prerendering';
...
const options = {
document: params.data.originalHtml,
url: params.url,
extraProviders: [
provideModuleMap(LAZY_MODULE_MAP),
{ provide: APP_BASE_HREF, useValue: params.baseUrl },
{ provide: 'MY_ARRAY_OF_VALUES', useValue: params.selectValues },
]
};
Then inject it wherever you want in your application.
@Inject(MY_ARRAY_OF_VALUES) private selectValues:string[]
Not tested I am not sure it works with arrays.So you may want to change the supplied data format to JSON with Newtonsoft.Json and deserialize it in Angular application.
Upvotes: 3
Reputation: 6546
I guess the solution that you have proposed is best so-far solution to request options
from server and populate them in your select
. But I am not understanding the other point that you make about hardcoding the logic and assumptions about values. Firstly if you are going to create an Enum
then you already have a set of values and is a kind of assumption that you make.
Upvotes: 0
Reputation: 336
If I have understood your problem correctly, you want your form fields as dynamically populated.Suppose 3 form fields 1.Country 2.State 3.City You want State to be populated based on country. Then you can very well go with the solution that is provided above. And if you want to play with your fields around then please note Web api only gives you a response.In MVC view depends on your model but here this is not the case.So to tackle this situation either you hard code logic in client side based on values or you choose your web api response model to have some attribute extra which contains info to play with your form fields.
Currently I am working on same kind of project angaulr 4 with ts MVC+web api
Upvotes: 0
Reputation: 4733
One idea I got is to do something like:
<select>
.Its pretty easy to make an Angular Service to do HTTP requests and get responses, you then put the possible choices in a variable in your component and then your View consumes that variable.
Upvotes: 2