How to Update data in Modal using Angular2? - html

This is My Angular2 part.Here Updateuser function for update data in database
export class UserprofileComponent
{
getdata : string;
public data;
Username : any ;
Firstname :any;
updateuser(){
let re = /[?&]([^=#&]+)=([^&#]*)/g;
let match;
let isMatch = true;
let matches = {};
while (isMatch)
{
match = re.exec(window.location.href);
if (match !== null)
{
matches[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
if (match.index === re.lastIndex)
{
re.lastIndex++;
}
}
else {
isMatch = false;
}
}
console.log(matches);
var headers= new Headers({'Content-Type' : 'application/x-www-form-urlencoded '});
var body = JSON.stringify({
username1 : this.user.Username,
firstname1 : this.user.Firstname,
})
this.http.post('../widgets/Update.php?ID='+matches['ID'],body, {
headers:headers; })
.map(res => res.json())
.map(res => {
if(res.success)
{
this.m=res.Message;
}
else{
this.m="wrong";
}
})
.subscribe(
data =>this.getdata = JSON.stringify(data),
err => console.error(err),
() => console.log('done'));
}
}
This is My html part:
<ngl-modal header=" Edit Profile" [(open)]="opened" [size]="size">
<div body>
<div class="form-horizontal" style="margin:auto;" id="editForm" *ngFor="#user of getdata">
<div class="form-group">
<label class="col-md-3 control-label">Username:</label>
<div class="col-md-8">
<input type="text" class="form-control" id="cname" [(ngModel)]="user.Username" />
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">Firstname:</label>
<div class="col-md-8">
<input type="text" class="form-control" id="ads" [(ngModel)]="user.Firstname"/>
</div>
</div>
<span>{{m}}</span>
<button class="slds-button slds-button--neutral" (click)="cancel()">Cancel</button>
<button class="slds-button slds-button--neutral slds-button--brand" (click)="updateuser()">Save</button>
</ngl-modal>
Here I'd use modal for displaying the data which is display by ngFor.But I want to update this display data so how to do it?Because data is display by ngModel and when I'm taking the whole ngModel value for example if [(ngModel)]="user.name" then it showing the error that user is not define so what to do in this case??

My first guess would be trying let user of getdata instead of #user of getdata.
My second guess would be creating an Array of users getdata: Array<any> as a property of your class, instead of getdata:string, then assign to it.
My third guess: before you get the data, there are no users, so:
<div *ngIf='getdata' class="form-horizontal" style="margin:auto;" id="editForm" *ngFor="#user of getdata"> to make sure you don't try to access the object before it's there.
Before you call updateUser() there are no objects you could show, that's why users are undefined, as far as I can see.
Hope some of this helps, good luck.

Related

React - HTML form validation doesn't work

I work on a React project. I wrote HTML codes for create form. There is validation in HTML scripts. I wrote validations but validations doesn't work. The code is below. For example I want the relevant field to be red when the name is not entered or I want it to give a warning message when the name does not comply with the text rules. I must do it without any library. How can I fix it ?
import React, { Component } from 'react'
import EmployeeService from '../services/EmployeeService';
class CreateEmployeeComponent extends Component {
constructor(props) {
super(props)
this.state = {
id: this.props.match.params.id,
firstName: '',
lastName: '',
emailId: ''
}
}
componentDidMount(){
if(this.state.id === '_add'){
return
}else{
EmployeeService.getEmployeeById(this.state.id).then( (res) =>{
let employee = res.data;
this.setState({firstName: employee.firstName,
lastName: employee.lastName,
emailId : employee.emailId
});
});
}
}
saveOrUpdateEmployee = (e) => {
e.preventDefault();
let employee = {firstName: this.state.firstName, lastName: this.state.lastName, emailId: this.state.emailId};
console.log('employee => ' + JSON.stringify(employee));
// step 5
if(this.state.id === '_add'){
EmployeeService.createEmployee(employee).then(res =>{
this.props.history.push('/employees');
});
}else{
EmployeeService.updateEmployee(employee, this.state.id).then( res => {
this.props.history.push('/employees');
});
}
}
changeFirstNameHandler= (event) => {
this.setState({firstName: event.target.value});
}
changeLastNameHandler= (event) => {
this.setState({lastName: event.target.value});
}
changeEmailHandler= (event) => {
this.setState({emailId: event.target.value});
}
cancel(){
this.props.history.push('/employees');
}
getTitle(){
if(this.state.id === '_add'){
return <h3 className="text-center">Add Employee</h3>
}else{
return <h3 className="text-center">Update Employee</h3>
}
}
onSubmit = e => {
e.preventDefault();
}
render() {
return (
<div>
<br></br>
<div className = "container">
<div className = "row">
<div className = "card col-md-6 offset-md-3 offset-md-3">
{
this.getTitle()
}
<div className = "card-body">
<form onSubmit={this.onSubmit} noValidate>
<div className = "form-group">
<label for="validationCustom01" class="form-label">First name</label>
<input type='text' maxLength={20} pattern='[A-Za-z]' placeholder="First Name" name="firstName" className="form-control"
value={this.state.firstName} onChange={this.changeFirstNameHandler} required/>
</div>
<div className = "form-group">
<label> Last Name: </label>
<input type='text' maxLength={20} pattern='[A-Za-z]'class="form-control" placeholder="Last Name" name="lastName" className="form-control"
value={this.state.lastName} onChange={this.changeLastNameHandler} required/>
</div>
<div className = "form-group">
<label> Email Id: </label>
<input type='email' maxLength={35} pattern='[A-Za-z]' placeholder="Email Address" name="emailId" className="form-control"
value={this.state.emailId} onChange={this.changeEmailHandler} required/>
</div>
<button type="submit" className="btn btn-success" onClick={this.saveOrUpdateEmployee}>Save</button>
<button className="btn btn-danger" onClick={this.cancel.bind(this)} style={{marginLeft: "10px"}}>Cancel</button>
</form>
</div>
</div>
</div>
</div>
</div>
)
}
}
export default CreateEmployeeComponent
Remove noValidate from your <form> element.
Additionally, I've personally found that Formik and Yup can be a helpful library.
(Sorry I missed that "no libraries" wasa constraint)
Edit:
I was a muppet and forgot to change the pattern
You can do one of 2 things:
Remove maxLength and change the pattern to pattern="[A-Za-z]{1,20}"
Where 20 will be the new max-length (so 20 or 35, depending on the field)
Only change the pattern to be pattern="[A-Za-z]+"
The + is needed to ensure 1 or more of the [A-Za-z] regex is done. https://regexr.com/
Also don't forget to remove noValidate from your <form> element.
This answer may also prove helpful in setting custom validity status messages and callbacks.

Uncaught (in promise) TypeError: Converting circular structure to JSON

I am receiving the following error here
body: JSON.stringify({
name,
expiresAfterSeconds
})
TypeError: Converting circular structure to JSON
--> starting at object with constructor 'FiberNode'
The problem seems to be circular structures cannot be converted using JSON stringify. However, I can't seem to locate a place where I am using circular structures. Am I missing something here?
Sample circular structure :
var a = {};
a.b = a;
fetchItems
async function fetchItems(name, expiresAfterSeconds) {
const newItemData = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name,
expiresAfterSeconds
})
};
const response = await fetch('/api/add-item', newItemData)
.then(response => response.json())
.then(data => console.log(data));
}
newItemForm()
const NewItemForm = () => {
const [itemData, setItemData] = React.useState({
name: '',
expiresAfterSeconds: ''
});
const handleSubmit = (e) => {
e.preventDefault();
fetchItems(itemData.name, itemData.expiresAfterSeconds)
}
return (
<form onSubmit={handleSubmit}>
<div className="form-row">
<div className="form-group col-md-8">
<label htmlFor="formItemName">Item name</label>
<input
type="text"
className="form-control"
id="formItemName"
aria-describedby="itemNameHelp"
placeholder="yummy food"
value={itemData.name}
onChange={(e) => { setItemData({ ...itemData, name: e.target.value }) }}
/>
<small id="itemNameHelp" className="form-text text-muted">
We don't want more than one piece of the same food in our fridge.
</small>
</div>
</div>
<div className="form-row">
<div className="form-group col-sm-3">
<label htmlFor="formExpiresAfterSeconds">Expires after</label>
<div className="input-group">
<input
type="text"
className="form-control"
id="formExpiresAfterSeconds"
aria-label="Expires in"
aria-describedby="basic-addon2"
value={itemData.expiresAfterSeconds}
onChange={(e) => { setItemData({ ...itemData, expiresAfterSeconds: e.target.value }) }}
/>
<div className="input-group-append">
<span className="input-group-text" id="basic-addon2">
seconds
</span>
</div>
</div>
</div>
</div>
<button type="submit" className="btn btn-primary" onClick={fetchItems}>
Submit
</button>
</form>
)
};
Edit- Full Error
TypeError: Converting circular structure to JSON
--> starting at object with constructor 'FiberNode'
| property 'stateNode' -> object with constructor 'HTMLButtonElement'
--- property '__reactInternalInstance$xcvrnuhmmp' closes the circle
try with
body: JSON.stringify({
name : name,
expiresAfterSeconds : expiresAfterSeconds
})

Is there anyway to authenticate the user type(user and Supplier) without any token in react and go with different page when I fetch the response api?

is it anyway or solution that can authenticate the result in response JSON without any token authentication? My project have two type of user (user=1 and supplier=2). I need both of this user has different pages when they login to my system. The response JSON are as below:
This user is normal user will go to user page, while other user with user type of 2 will go to supplier page.
Here is my code:
login(){
if(this.state.loginEmail && this.state.loginPassword){
PostData('api/users/login', this.state).then ((result) => {
let responseJSON = result;
console.log(responseJSON)
if(responseJSON.user){
sessionStorage.setItem('user', responseJSON);
// console.log("Home Page")
this.setState({redirect: true});
}else{
console.log("Login Error")
alert("wrong user credential")
}
});
}
}
On the render component, when user login successfully I use redirect to go to Home page"/home":
render(){
if(this.state.redirect){
return (<Redirect to={{
pathname: '/home',
state: { loginEmail : this.state.loginEmail }}}/>)
}
if(sessionStorage.getItem("user")){
return (<Redirect to ={'/home'}/>)
}
return (
<div className="login-background">
<div className = " login-form">
<h1>Login</h1>
<div className = "txtb">
<input type="text" name="loginEmail" placeholder= "email" onChange={this.onChange}/>
</div>
<div className = "txtb">
<input type="password" name="loginPassword" placeholder="password" onChange={this.onChange}/>
</div>
<input type="submit" value="Login" className="logbtn" onClick={this.login}/>
<div className = "bottom-text">
Dont have account? Sign up
</div>
</div>
</div>
);
}
What I want is when userType is equal to 2, they will go to supplier page "/supplier".
Assuming that you have already connected your component with react-router, this is how you can redirect your user to the respective paths based on the userType.
login(){
if(this.state.loginEmail && this.state.loginPassword){
PostData('api/users/login', this.state).then ((result) => {
const { data: { user_info: { userType } } } = result;
if (userType === 1) {
history.push('/home');
} else if (userType === 2) {
history.push('/supplier')
}
});
}
}

how can I disable a button in angular 2 without using a form group

I just need to enable the button if all the forms is filled and disable it if not
**here is my code : **
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form [formGroup]="OvertimeForm" (ngSubmit)="createOvertime()">
<div class="form-group">
<label class="control-label" for="employee" >Employee:</label>
<select2 [data]="employee"
[options]="options"
[width]="570"
[value]="employee_value"
(valueChanged)="changed($event)"
required>
</select2>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<label>Start Time:</label>
<timepicker [(ngModel)]="start_time" [showMeridian]="ismeridian" formControlName="start_time" ></timepicker>
<button type="button" class="btn btn-info" (click)="toggleMode()">12H / 24H</button>
</div>
<div class="col-md-6">
<label>End Time:</label>
<timepicker [(ngModel)]="end_time" [showMeridian]="ismeridian" formControlName="end_time" ></timepicker>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-12">
<label>Reason</label>
<textarea class="form-control" name="remarks" id="remarks" rows="3" placeholder="Reason ..." formControlName="remarks" required></textarea>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary pull-right" [disabled]="!OvertimeForm.valid">Add</button>
</form>
but [disabled]="!OvertimeForm.valid" is not working
I use different package like time picker and select 2, they have their own function in getting their values
this is the code in my component
this.OvertimeForm = _fb.group({
'start_time': [this.ot.start_time, [Validators.required]],
'end_time': [this.ot.end_time, [Validators.required]],
'remarks': [this.ot.remarks, [Validators.required]],
'created_by': [this.ot.created_by, [Validators.required]]
});
}
ngOnInit() {
this.get_employee();
this.get_UserId();
}
get_UserId(){
this._auth_service.getUser().
subscribe(
data => {
let user = data; // fetched
this.user_id = user.id;
this.OvertimeForm.value.created_by = this.user_id;
},
err => console.error(err)
);
}
get_employee(){
let employees = this._common_service.getEmployees().
subscribe(
data => {
this.emp = Array.from(data); // fetched record
this.employee = this.emp;
this.employee_value = [];
this.options = {
multiple: true
}
this.current = this.employee_value;
},
err => console.error(err)
);
}
changed(data: any) {
this.current = data.value;
this.OvertimeForm.value.employee_id = this.current;
this.OvertimeForm.value.start_time = moment(this.start_time).format("HH:mm:ss");
this.OvertimeForm.value.end_time = moment(this.end_time).format("HH:mm:ss");
// this.OvertimeForm.valid = true;
// console.log(this.OvertimeForm.valid);
}
remarks(event:any){
let a = event;
console.log(a);
}
createOvertime(){
let ot = this.OvertimeForm.value;
console.log(ot);
this._OTservice
.createOT(ot)
.subscribe(
data => {
this.poststore = Array.from(data);
this.success_title = "Success";
this.success_message = "A new user record was successfully added.";
setTimeout(() => {
this.close();
}, 1000);
},
err => this.catchError(err)
);
}
private catchError(error: any){
let response_body = error._body;
let response_status = error.status;
if( response_status == 500 ){
this.error_title = 'Error 500';
this.error_message = 'The given data failed to pass validation.';
} else if( response_status == 200 ) {
this.error_title = '';
this.error_message = '';
}
}
//time picker
public toggleMode():void {
this.ismeridian = !this.ismeridian;
}
try this,
<button type="submit" [disabled]="!ngForm.valid">Submit</button>
Replace form tag line with :
<form #OvertimeForm=ngForm novalidate (ngSubmit)="createOvertime()">
Use: [attr.disabled]="!OvertimeForm.valid"
use novalidate in your form tag.
please find below code for reference.
OvertimeForm.html
<form [formGroup]="myNgForm" novalidate (ngSubmit)="saveAsConfirm(myNgForm)">
////other elements
<button type="submit" class="btn btn-success" [disabled]="!myNgForm.valid">Save</button>
</form>
hope this will help you.

MVC5 Mqsql Issue

After Update of Model from database in Entity Framework. Json Data not populate into textbox. when i use DeveloperTool i found a error "There is already an open DataReader associated with this Connection which must be closed first."[Error 505] Help me for resolve this problem.am using MySql in my project. When i use only one table in Model then i didn't get any error but when i update model then my project not working. If i add all the tables in Model then I face same problem.
Here is my code
Controller:-
// GET: Chains
public ActionResult Index()
{
ViewData["chain_name"] = new SelectList(db.chains, "code", "name");
return View(db.chains.ToList());
}
//Action Function callby javascript
[HttpPost]
public ActionResult Action(string code)
{
var query = from c in db.chains
where c.code == code
select c;
return Json(query);//Return Json Result
}
View:-
#using (#Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
<div class="form-group">
<label class="col-sm-2 control-label">
Select Chain
</label>
<div class="col-md-3">
#Html.DropDownList("ddlchainname", (SelectList)ViewData["chain_name"], new { onchange = "Action(this.value);", #class = "form-control" })
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">
Chain Name
</label>
<div class="col-md-3">
#Html.TextBox("ChainName", null, new { #class = "form-control" })
</div>
<label class="col-sm-2 control-label">
Username
</label>
<div class="col-md-3">
#Html.TextBox("username", null, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">
Chain Code
</label>
<div class="col-md-3">
#Html.TextBox("ChainCode", null, new { #class = "form-control" })
</div>
</div>
</div>
}
<script type="text/javascript">
function Action(code) {
$.ajax({
url: '#Url.Action("Action", "Chains")',
type: "POST",
data: { "code": code },
"success": function (data) {
if (data != null) {
var vdata = data;
$("#ChainName").val(vdata[0].name);
$("#ChainCode").val(vdata[0].code);
$("#username").val(vdata[0].username);
}
}
});
}
Try this approach:
using (var db = new ChainEntities())
{
ViewData["chain_name"] = new SelectList(db.chains, "code", "name");
return View(db.chains.ToList());
}
This way you open the connection only once then dispose when done.
Sane for action:
[HttpPost]
public ActionResult Action(string code)
{
using (var db = new ChainEntities())
{
var query = from c in db.chains
where c.code == code
select c;
return Json(query);//Return Json Result
}
}