Can't clear the angular-json-schema-form after submitting - json

I'm building a form using json-schema-form and am using this library.
https://www.npmjs.com/package/angular6-json-schema-form
This looks great but I have one problem.
After submitting, I want to clear the form, but it's impossible.
I couldn't find out the method in the document, and also searched the stackoverflow and googled, but got no solution.
So I cleared the form using Javascript after submitting, but the form data seems to be saved somewhere, so it's possible to resubmitting without any action.
Here is the code
<json-schema-form
*ngIf="isInquireForm"
class="contact-form"
loadExternalAssets="true"
framework="no-framework"
[options]="inquireFormOption"
[schema]="inquireFormSchema"
[form]="inquireFormLayout"
(onSubmit)="onInquireSubmit($event)"
(isValid)="inquireIsValidFn($event)"
(validationErrors)="inquireValidationErrorsFn($event)">
</json-schema-form>

You need to create an object to populate the form with default values and bind it to the json schema form component. When you need to reset, clear the data in the object.
data = {
first_name: "abc",
last_name: "xyz"
}
<json-schema-form
*ngIf="isInquireForm"
class="contact-form"
loadExternalAssets="true"
framework="no-framework"
[options]="inquireFormOption"
[schema]="inquireFormSchema"
[form]="inquireFormLayout"
[(data)]="data"
(onSubmit)="onInquireSubmit($event)"
(isValid)="inquireIsValidFn($event)"
(validationErrors)="inquireValidationErrorsFn($event)">
</json-schema-form>
And to clear the form, reset data
data = {
first_name: "",
last_name: ""
}

Related

How to send an Enum variant as integer, not string in Angular

I'm using Angular 11, and have to post some data to a backend service. Here's the data I need to post:
interface User {
id: Guid; // Guid is just a type alias to string, with some validation checks
email: string;
role: Role
}
enum Role {
User = 0,
Administrator = 1
}
Now the problem comes when I try to post to my backend using the default HttpClient from Angular. Here's the code:
createOrUpdateUser(user: User): Observable<User> {
return this.http.post<User>(`${this.baseUrl}/${this.userUrl}/${this.userCreateOrUpdate}`, user);
}
This works fine, but the JSON sent is "wrong". It sends this:
{
"id": "2abe50d6-4c81-4ace-ad95-c8182d4384a3",
"email": "someEmail#example.org",
"role": "0"
}
Where as the backend is expecting this
{
"id": "2abe50d6-4c81-4ace-ad95-c8182d4384a3",
"email": "someEmail#example.org",
"role": 0
}
The difference being the backend expects "role": 0, but Angular sends "role": "0". How can I make Angular send "role": 0?
This is may not be a good idea. But it will be helped you.
createOrUpdateUser(user: User): Observable<User> {
user.role = Number(user.role);
return this.http.post<User>(`${this.baseUrl}/${this.userUrl}/${this.userCreateOrUpdate}`, user);
}
you can use + to make it as number before sending it api user.role = +user.role. Some where else you are assigning value of role in user object which is making it as a string. its not enum issue.
TypeScript is compiled to plain old javascript code, where type enforcement is more or less non-existent. This means that, in theory, you might be assigning a string to your User model.
There can be multiple reason - i.e. you receive it this way from backend, assign it to a variable and re-send later without modifying the value. Or, for example, the User comes from a FormGroup which passes the value as a string. You can even have TypeScript code omit type checks:
let user: User = {
id: '2abe50d6-4c81-4ace-ad95-c8182d4384a3',
email: 'someEmail#example.org',
role: Role.Administrator
}
user['role'] = "2" // Not a valid enumeration
So, to instead of going for some strange workaround like using +user.role in the mapping, perhaps look for where / how the value is assigned in the first place.
As it is not really clear if it gets sent from angular or received from server as string we can debug a bit to find the right place to investigate (angular frontend or backend)
You can investigate by logging console.log(typeof user.role)and see what it returns. Also have a look at what gets sent from frontend to backend using Chrome Devtools -> Network -> click on the request -> and scroll down on first tab to see what data gets sent.
What might happen is frontend to send the right data type (integer) for the role and backend interpret it as string.
In this case you could just use parseInt(user.role) in the backend as a fallback or investigate how to get the integer type on the backend body request instead of string.

GSuite Admin SDK > Directory API: How do I add values to a custom schema for a user?

We are setting up some automation around SSO into AWS, but I have run into a problem.
There is a custom user attribute called AWSLab, and if a user does not have any IAMRole values populated for this attribute, then I need to add one.
The IAMRole field has Info type set to Text and No. of values set to Multi-value on the GSuite side, so I am putting it into an array for this API request.
Also, when I do a GET on the user and look at other schemas attached, I see this key named type set to work so I include that too.
Below is my function in Google Apps Script:
function check_user_access(){
var email = 'user#domain.com';
var role = [
'arn:aws:iam::123456789012:role/User',
'arn:aws:iam::123456789012:saml-provider/GoogleAppsProvider'
].join(',')
optArgs = {
projection: "full"
}
var user = AdminDirectory.Users.get(email, optArgs)
var schema = user.customSchemas
Logger.log("typeof(schema): %s", typeof(schema))
if(schema["AWSLab"]) {
Logger.log("schema[\"AWSLab\"] found on user '%s': %s", email, schema["AWSLab"])
} else {
Logger.log("schema[\"AWSLab\"] not found! Updating...")
Logger.log("schema before:\n\n%s\n", JSON.stringify(schema))
schema["AWSLab"] = { "IAMRole": [{ "type": "work", "value": role }] }
Logger.log("schema after:\n\n%s\n", JSON.stringify(schema))
AdminDirectory.Users.update(userFull, email) // line 35
}
}
When this function runs, I see this error:
Invalid Input: [AWSLab] (line 35, file "Labs")
I have some extra lines in there right now, to output some details for troubleshooting, but it's not helping me see the problem.
As it turns out, the issue was with the name of the custom schema.
At creation, the schema had a different name which was then edited at some point.
The key to figuring this out was populating the schema fields in question on a user with some dummy data, then pulling the user out via the API with a GET and examining the JSON.

Get type information from json for form validation with vue 2

I want to do form validation with Vue 2. The problem is that I want to use information from the server. For each field I can add things like max string length, required, type, ... to the json result.
Does something like this already exists? Is there a common used format for this?
Is there a good plugin for Vue that I can use for this. I already found form validation plugins, but I don't want to bind each setting on each input manually.
I was thinking about a validation object that I could bind to a form. But maybe I'm reinventing the wheel?
This is how I usually do it:
In template, let's say you have something like this:
<form>
<input #keyup="keyUpHandler('firstName')" v-model="firstName" />
<input #keyup="keyUpHandler('lastName')" v-model="lastName" />
<input #keyup="keyUpHandler('email')" v-model="email" />
</form>
In JS:
data: {
firstName: '',
lastName: '',
email: ''
},
methods: {
keyUpHandler: _.throttle((type) => {
sendStuffToServer(this[type])
.then(response => {
// if there's an error, then show error
})
}, 2000)
}
I used lodash to do debounce, so sendStuffToServer will only execute when the user is done typing for 2 seconds. You may come across the debounce filter in Vue, but it's already removed in 2.0, so use lodash instead.

KnockoutJS dynamic form validation

I have a form that have a three field group that on a click of a "Add New" buttom other three field group will be added. That part is working great.
I want to add a validation so all three fields are required in order to add a new group.
For reference here is the code working: http://jsfiddle.net/5g8Xc/
var ContactsModel = function(contacts) {
var self = this;
self.contacts = ko.observableArray(ko.utils.arrayMap(contacts, function(contact) {
return { firstName: contact.firstName, fathersLast: contact.fathersLast, country: contact.country };
}));
self.addContact = function() {
self.contacts.push({
firstName: "",
fathersLast: "",
country: ""
});
};
self.removeContact = function(contact) {
self.contacts.remove(contact);
};
};
Any clue on how to implement this validation? I was trying to use jquery validation to do that but I think that is possible with KnockoutJS.
Appreciate any advice.
As stated already, the validation plugin will be the most elegant, less re-inventive solution.
Edit: After commentary implementation utilizing validation plugin
With that aside, you have a couple options.
If you are confident the contact object will always contain only required fields, a not very robust implementation would be iterate over the properties of the contact ensuring each has some value.
A little more robust, but still lacking the elegance of the plugin, implementation would be to maintain an array of required fields and use that array for validation. You can reference my example for this setup. Essentially, each required property is mapped to observables. Changes made to the value of any observable property triggers (via a subscription) a mutation call for a dummy observable that is used in a computed. This is required since a computed can't call valueHasMutated. The mutation call triggers the computed to reevaluate, thus updating the UI.

calling JSON webservice & using html

I've been using XML a lot lately but now I'm practicing with some JSON.
What I am trying to do is make a button and text box - so the user can type in a zip code and it will get the info for that zip code...
Using JSON from geonames.org
It's frustrating me trying to figure this out, I've found it easy when I was making my own files with XML but now I am trying to use an actual website and JSON.
Please show me how to do this! Would appreciate it! Thanks.
First of all HTML cannot process a json response from a server. You can send a get or post in json format to a server and get a json response back but you need something other than HTML to process that JSON message. Browsers can format and display XML but not JSON (they just display it as a string). The easiest way to do that in a browser is use JavaScript. For this I would recommend using the jquery library.
http://jquery.com
Here's an example of some jquery I used recently to process a returned JSON string.
$(document).ready(function() {
$(".img a").on("click", function(event) {
event.preventDefault();
var item;
if ((item= $(this).attr( 'href' ))=="saved") return false;
$(this).html("<div style='line-height:4em '>Saved</div>");
$(this).attr("href","saved");
var action ="add";
jqxhr = $.post("webservice.php", { action: action, color: item }, function(data) {
var result=data.result;
if (result=="saved") {
self.html("<div>Saved</div>");
self.attr("href","saved");
}
}, "json")
.error(function() {
alert("error: unable to contact web service");
});
});
});
The returned JSON string from this request is { result: saved }. So as you can see you access the associated array as part of the data object. In my case data.result provided me with the value of result from the json string.
Note my example is for using an anchor tag to pass a value to send in the webservice call. In your case you will need to use a form.
If you're using jeoquery then just look at the html source of UI sample. It's showing the same autocomplete box that you might be trying to implement no custom code to write to parse returned JSON. Below code should work for you:
<input class="input-large" id="city" type="text"/>
$("#city").jeoCityAutoComplete();