Angular Detect change on html input element or trigger it automatically - html

I want to get the value of an input element once it changes. The value is not typed by the user. I got it from a source and bind it with [(ngModel)] or just [value]. I have tried everything. But I still got nothing. I even search on how to trigger an event manually. if some of you can help me, I would be grateful
My code: I have tried various things. But this is the one that seems to work. But this instructions in the subscribe method was executed twice
this.maxGroup$ = this.reponseService.getMaxGroupe();
this.maxGroup$.subscribe((rep: MaxGroup) => {
if (rep) {
this.maxGroupe = rep;
this.max = rep.valeur;
this.questions.forEach(q => {
let r = new Reponse();
r.QuestionId = q.Id.toString();
r.Question = q;
r.Groupe = rep.valeur;
this.reponses.push(r);
});
}
this.max++;
this.maxGroupe.valeur = this.max;
let ref = this.reponseService.createMax(this.maxGroupe);
this.reponseService.deleteMax(this.idMax);
});
In my service:
return this.db.list('/maxGroup').snapshotChanges().map(snapshots => {
return snapshots.map(c => ({ key: c.payload.key, ...(c.payload.val()) as {} }));
});
In my template:
<div *ngFor="let m of maxGroup$ | async">
<input #KeyMax type="text" id="keyMax" [(ngModel)]="m.key" [value]="m.key" (change)="keyChange()"/>

Related

Change the input initial value of controlled component in React

I have this input component
const FOO = props => {
const [inputValue, setInputValue] = useState(
props.editState ? props.initialValue : ""
);
const setSearchQuery = (value) => {
setInputValue(value);
props.onSearch(value);
};
return (
<input
placeholder="Select ..."
onChange={(e) => {
setSearchQuery(e.target.value);
}}
value={inputValue}
/>
)}
I'm using it like this
const BAR = props => {
const [fetchedData, setfetchedData] = useState({
value : "" // to get rid of can't change controlled component from undefined error
});
const params = useParams();
//request here to get fetchedData
return(
<FOO
onSearch={(value) => {
searchSomethingHandler(value);
}}
initialValue={
params.ID
? fetchedData.value
: ""
}
editState={params.ID ? true : false}
/>
)}
I need to set the initial value of the fetched data into the input so the user could see the old value and edit it, if I pass the data (fetchedData) as props it works perfectly,
but if I get the data through API it wont set the value cause it's empty at the first render,
how can I solve this please?
You'll probably want to make use of the useEffect hook to run code when a value updates.
In FOO:
const FOO = props => {
// ...
useEffect(() => {
// This hook runs when props.initialValue changes
setInputValue(props.initialValue);
}, [props.initialValue]);
// ...
};
You can leave BAR the same as before, I think. Though, I would put the request to the API inside a useEffect hook with an empty dependency array so you're not querying it on every render.

How create a new input field row by clicking a button reactjs

I am building an ecommerce app and I want to collect the users different phone numbers and address.
I want to create a new field where the user types new phone number and address
I tried using state to accomplish the task but I am geting error
TypeError: contactInfo.phoneInputs is undefined
const RegisterModal = ({openRegisterModal, setOpenRegisterModal}) => {
const [contactInfo, setContactInfo] = useState({
phoneInputValue : {},
phoneInputs: [],
addressInputValue : {},
addressInputs: [],
})
console.log(contactInfo)
const addContact = (e) => {
e.preventDefault()
const contactsphoneInfo = "phoneNumber";
const contactsAddressInfo = "address";
let phoneInputBox =
<Input name={contactsphoneInfo} star="false" label="PhoneNumber" type="text" className="col-md-6" />
let addressInputBox =
<Input name={contactsAddressInfo} star="false" label="address" type="text" className="col-md-6" />
setContactInfo(contactInfo.phoneInputs.push({phoneInputBox}))
console.log(contactInfo)
}
return (
<div>
{
contactInfo.phoneInputs.map(input => input)
}
button onClick={addContact}>Add</button>
</div>
)
}
export default RegisterModal
How do I fix this error
link to codesandbox
https://codesandbox.io/s/distracted-morse-s6zn0
your setstate is a bit fishy, I believe
setContactInfo({...contactInfo, phoneInputs: [...contactInfo.phoneInputs,phoneInputBox ]});
This should work . but i recommend you try for more clean code .
and console.log(contactInfo) before render if you check itll be undefined if you want to check the inital value still use useEffect then log it .

How to use one request to local JSON file to populate multiple dropdowns, using jQuery?

I am trying to use Country/City dropdowns in multiple places of my project, however I am getting stuck with an unusual behaviour - when I am changing the countries. How can I make one request to get the local JSON file and populate multiple dropdowns?
Here is my code:
$(document).ready(function() {
fetch('assets/test.json').then(response => {return response.json()}).then(selectData => {
console.log(selectData)
function updateSelectsBirth() {
let citiesBirth = selectData[this.value].map((key, val) => {
return $("<option />").text(key).val(key);
});
$("#cityBirth, #cityBirth1").empty().append(citiesBirth);
}
let stateBirth;
$countryBirth = $("#countryBirth, #countryBirth1").on("change", updateSelectsBirth);
for (stateBirth in selectData) {
$("<option />").text(stateBirth).val(stateBirth).appendTo($countryBirth);
}
$countryBirth.change();
})
});
And the HTML
<select id="countryBirth"></select>
<select id="cityBirth"></select>
<br/>
<select id="countryBirth1"></select>
<select id="cityBirth1"></select>
Here's also a link to the demo project: link to the demo
The unexpected behaviour comes from
$("#cityBirth, #cityBirth1").empty().append(citiesBirth);
Because, when it's updating the cities, it's updating all the dropdowns instead of just one.
So you can try:
$(document).ready(function() {
fetch('assets/test.json').then(response => {return response.json()}).then(selectData => {
// console.log(selectData)
function updateSelectsBirth(event) {
let citiesBirth = selectData[this.value].map((key, val) => {
return $("<option />").text(key).val(key);
});
// console.log(event.data.target)
$(event.data.target).empty().append(citiesBirth);
}
let stateBirth;
$countryBirth = $("#countryBirth").on("change", {target: "#cityBirth"}, updateSelectsBirth);
$countryBirth1 = $("#countryBirth1").on("change", {target: "#cityBirth1"}, updateSelectsBirth);
// $countryBirth1 = $("#countryBirth1").on("change", updateSelectsBirth("#cityBirth1"));
for (stateBirth in selectData) {
$("<option />").text(stateBirth).val(stateBirth).appendTo($countryBirth);
$("<option />").text(stateBirth).val(stateBirth).appendTo($countryBirth1);
}
$countryBirth.change();
$countryBirth1.change();
})
});
I apologize this is not a complete answer, as I'm not generalizing to multiple dropdowns, however I am not able to leave comments yet. I hope this can still be helpful.

Angular Firebase Storage, Assigning User Input Properties to Real Time Database

I want to upload a file especially an image to my firebase storage. I found a tutorial from this link. I added the more properties like url and file to my existing class and i followed the function template on that link. But apparently i did something wrong. The file uploaded to my storage and the console log didn't return any error. I need help with assigning another properties like prdName, prdCategory, and prdSup with user input correctly. Can someone help me with this please?
//product.ts
export class Product {
$prdKey: string;
prdName: string;
prdCategory: string; //Category
prdSup: string; //supplier
prdDescription: string;
prdImage: string; //name
prdUrl: string; //url
file: File;
constructor(file: File) {
this.file = file;
}
}
//service.ts
variable: any;
selectedProduct: Product = new Product(this.variable); //-->there was an error here that said expected 1 argument but got 0 so i add variable:any;
private basePath = '/product';
pushFileToStorage(Product: Product, progress: {
percentage: number
}) {
const storageRef = firebase.storage().ref();
const uploadTask = storageRef.child(`${this.basePath}/${Product.file.name}`).put(Product.file);
uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED,
(snapshot) => {
// in progress
const snap = snapshot as firebase.storage.UploadTaskSnapshot
progress.percentage = Math.round((snap.bytesTransferred / snap.totalBytes) * 100)
},
(error) => {
// fail
console.log(error)
},
() => {
// success
/*--What should i assign here?--*/
Product.prdName = Product.file.name,
Product.prdCategory = Product.file.name,
Product.prdSup = Product.file.name,
Product.prdDescription = Product.file.name,
/*------------------------------------------*/
Product.prdUrl = uploadTask.snapshot.downloadURL,
Product.prdImage = Product.file.name,
this.saveFileData(Product)
}
);
}
private saveFileData(Product: Product) {
this.firebase.list(`${this.basePath}/`).push(Product);
}
//component.ts
upload() {
const file = this.selectedFiles.item(0);
this.currentFileUpload = new Product(file);
this.ProductService.pushFileToStorage(this.currentFileUpload, this.progress);
}
<!--component.html-->
<!--form snippet-->
<form #productForm="ngForm" (ngSubmit)="upload()">
<div class="form-group">
<label>Product Name</label>
<input class="form-control" name="prdName" #prdName="ngModel" [(ngModel)]="ProductService.selectedProduct.prdName">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
Please let me know if more snippets are needed. Thank you in advance.
(Update)
I put the push function inside //success condition, however i'm not sure what to assign for each class properties. Product.prdName = Product.file.name, will give me prdName equal to the file name. I tried Product.prdName = selectedProduct.prdName, but looks like it is not correct.
I figured it out, it should looks like this, works for me :D
() => {
// success
this.productList.push({
prdName: this.selectedProduct.prdName,
prdCategory: this.selectedProduct.prdCategory,
prdSup: this.selectedProduct.prdSup,
prdDescription: this.selectedProduct.prdDescription,
prdUrl: this.selectedProduct.prdUrl = uploadTask.snapshot.downloadURL,
prdImage: this.selectedProduct.prdImage = Product.file.name,
})
this.saveFileData(Product)
}

Angular Js: Typeahead

I have an input type which uses angularjs type-ahead.The problem I am facing is that it disappears when I move my mouse over it. I am able to use the arrow keys to select items from the list,but am unable to click and select from the list.
I am getting list from the database,and the typeahead list is populating fine. Other places I used almost the same code,it works fine. When using this particular typeahead, after a while,say 5-6 trials, it behaves normally.
Any help will be appreciated.Thanks.
My html:
<input
id="{{roleAssignmentTableDTO.employeeNumberElementId}}" type="text"
name="employeeNumber"
ng-disabled="roleAssignmentTableDTO.disableEmployee"
ng-model="roleAssignmentTableDTO.employeeNumber"
typeahead="state for state in states | filter:$viewValue" />
My Controller:
$http
.post('rest/employeeSearch', query)
.success(
function(dataList) {
/*$scope.roleAssignmentDTO.roleAssignmentTableDTOList[elementId].searchLoader = false;
roleAssignmentTableDTO.showSearchLink=true;*/
if (dataList.length == 0) {
/*$scope.projectNotfoundError = true;
$scope.roleAssignmentDTO.roleAssignmentTableDTOList[elementId].showSearchLink = false;
$scope.projectNotfoundErrorMsg = 'You entered incorrect employee';*/
}
$.each(
dataList,
function(
i,
data) {
map[data.employeeNumber] = data;
List
.push(data.employeeNumber);
});
process(List);
})
.error(
function() {
$scope.roleAssignmentDTO.roleAssignmentTableDTOList[elementId].searchLoader = false;
$scope.projectNotfoundError = true;
$scope.projectNotfoundErrorMsg = 'Some Internal error occured';
List
.push("no data found");
process(List);
});
},
updater : function(selectedData) {
$scope.roleAssignmentDTO.roleAssignmentTableDTOList.employeeNumber = selectedData;
return selectedData;
}
});