Angular2 submit a form to the server - http

I have googled for this problem and I found a lot of links which couldn't help me solve my problem. All I want to do is to send forms data to the controller. it goes to the controller but the data is not present in there.
here are my codes:
app.component.ts
import {Component, OnInit} from "angular2/core";
import {AsyncRoute, Router, RouteDefinition, ROUTER_PROVIDERS, RouteConfig, Location, ROUTER_DIRECTIVES, RouteParams} from "angular2/router";
import {CitiesComponent} from "./components/cities.component";
import { CitiesService } from './components/cities.service';
import { HTTP_PROVIDERS } from 'angular2/http';
import 'rxjs/Rx';
declare var System: any;
#Component({
selector: "app",
templateUrl: "/app/app.html",
providers: [CitiesService, HTTP_PROVIDERS, ROUTER_PROVIDERS],
directives: [ROUTER_DIRECTIVES]
})
export class AppComponent implements OnInit {
public routes: RouteDefinition[] = null;
constructor(private router: Router,
private location: Location) {
}
ngOnInit() {
if (this.routes === null) {
this.routes = [
new AsyncRoute({
path: "/City",
name: "City",
loader: () => System.import("app/components/cities.component").then(c => c["CitiesComponent"])
})
];
this.router.config(this.routes);
}
}
getLinkStyle(route: RouteDefinition) {
return this.location.path().indexOf(route.path) > -1;
}
}
cities.ts
export interface ICities {
Id: string;
State: string;
Title: string;
}
cities.component.ts
import {Component, OnInit} from "angular2/core";
import { FORM_DIRECTIVES } from 'angular2/common';
import { RouteParams, Router } from 'angular2/router';
import { ICities } from './cities';
import { CitiesService } from './cities.service';
#Component({
selector: "cities",
templateUrl: "/partial/cities",
directives: [FORM_DIRECTIVES]
})
export class CitiesComponent implements OnInit {
public City: ICities;
cities: ICities[];
errorMessage: string;
constructor(private _citiesService: CitiesService, private _router: Router,
private _routeParams: RouteParams) { }
ngOnInit() {
this._citiesService.getCities()
.subscribe(
cities => this.cities = cities,
error => this.errorMessage = <any>error);
//this.message = "anything!"
}
onSubmit(form: ICities): void {
console.log('you submitted value 23:', form);
this._citiesService.addCity(form);
}
}
cities.services.ts
import { Injectable } from 'angular2/core';
import { Http, Response, Headers, RequestOptions, RequestMethod, Request} from 'angular2/http';
import { Observable } from 'rxjs/Observable';
import { ICities } from './cities';
#Injectable()
export class CitiesService {
private _citiesInsert = '/Cities/CitiesInsert';
private _citiesList = '/Cities/GetCities';
constructor(private _http: Http) { }
getCities(): Observable<ICities[]> {
return this._http.get(this._citiesList)
.map((response: Response) => <ICities[]>response.json())
.do(data => console.log('All: ' + JSON.stringify(data)))
.catch(this.handleError);
}
addCity(city: ICities) {
let body = JSON.stringify({ city });
let headers = new Headers({ 'Content-Type': 'application/json' });
//let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers });
var url = '/Cities/CitiesInsert';
this._http.post(this._citiesInsert, JSON.stringify(city), headers)
.map(this.extractData)
.catch(this.handleError)
.subscribe(
(res2) => {
console.log('subsribe %o', res2)
}
);
}
private extractData(res: Response) {
let body = res.json();
alert("extract data: " + body);
return body.data || {};
}
private handleError(error: Response) {
// in a real world app, we may send the server to some remote logging infrastructure
// instead of just logging it to the console
alert("error: " + error);
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
cities.cshtml
<cities>
<div class="col-md-12">
<div class="portlet box blue ">
<div class="portlet-title">
<div class="caption">
<i class="fa fa-gift"></i> مشخصات
</div>
<div class="tools">
<a title="" data-original-title="" href="" class="collapse"> </a>
<a title="" data-original-title="" href="#portlet-config" data-toggle="modal" class="config"> </a>
<a title="" data-original-title="" href="" class="reload"> </a>
<a title="" data-original-title="" href="" class="remove"> </a>
</div>
</div>
<div class="portlet-body form">
<form role="form" #f="ngForm" (ngSubmit)="onSubmit(f.value)" >
<div class="form-body">
<div class="row">
<div class="col-sm-8">
<div class="form-group">
<label>وضعیت</label>
<select ngControl="State" class="form-control input-small selectpicker">
<option value="ACTIVATED" selected="selected">فعال</option>
<option value="DEACTIVE">غیرفعال</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-8">
<div class="form-group">
<label>عنوان</label>
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-envelope"></i>
</span>
<input class="form-control" ngControl ="Title" placeholder="عنوان شهر" type="text">
</div>
</div>
</div>
</div>
</div>
<div class="form-actions right">
<button class="btn">
<i class="fa fa-ban"></i> صرفنظر
</button>
<button class="btn green" type="submit">
<i class="fa fa-save"></i> ذخیره
</button>
</div>
</form>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="portlet mt-element-ribbon light portlet-fit ">
<div class="ribbon ribbon-right ribbon-clip ribbon-shadow ribbon-border-dash-hor ribbon-color-success uppercase">
<div class="ribbon-sub ribbon-clip ribbon-right"></div> لیست اطلاعات
</div>
<div class="portlet-title">
<div class="caption">
<i class="icon-layers font-green"></i>
<span class="caption-subject font-green bold uppercase">شهرها</span>
</div>
</div>
<div class="portlet-body">
<div class='table-responsive'>
<table class='table' *ngIf='cities && cities.length'>
<thead>
<tr>
<th>
Title
</th>
</tr>
</thead>
<tbody>
<tr *ngFor='#city of cities'>
<td>{{ city.Title }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</cities>
CitiesController.cs
[HttpPost]
public void CitiesInsert(Cities city)
{
Console.Write(city);
}

Try something like this:
<form [ngFormModel]="loginForm" (submit)="doLogin($event)"
and in your component
doLogin(event) {
console.log(this.loginForm.value);
event.preventDefault();
}

Related

Vue 3 + Vee-validate 4 - handleSubmit does not getting triggered

I am new to Vue and learning Vue using composition API. Now I am stuck on the validation and form submitting process. I am using VeeValidate for validation and form submission. I am handleSubmit function for form submission, but this is not getting triggered at all.
I have tried creating the form as per the documentation but how I messed up. Any help would be appreciable
<template>
<div class="modal-dialog modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Add Layout </h4>
<a class="modal-close" #click="isModalOpen = !isModalOpen"><i class="fa fa-times"></i></a>
</div>
<form autocomplete="off" #submit="onSubmit">
<div class="modal-body">
<div class="row">
<div class="col-md-12 col-lg-12">
<div class="mb-3">
<label class="form-label">Layout Name:<span class="text-danger">*</span></label>
<div class="form-group">
<input type="text" name="layoutName" v-model="layoutName" class="form-control"
maxlength="50" placeholder="Enter Layout Name"
:class="{ 'is-invalid': layoutNameError }" />
<div class="invalid-feedback">{{ layoutNameError }}</div>
</div>
</div>
</div>
<div class="col-md-6 col-lg-6 col-sm-12 col-xs-12">
<div class="mb-3">
<label class="form-label">Module:<span class="text-danger">*</span></label>
<div class="form-group">
<Dropdown name="moduleId" v-model="moduleId" :options="moduleList"
optionLabel="text" placeholder="Select Module" class="widthAll"
#change="onChangeModule($event.value)" :editable="true" :filter="true"
:showClear="true" />
</div>
</div>
</div>
<div class="col-md-6 col-lg-6 col-sm-12 col-xs-12">
<div class="mb-3">
<label class="form-label">Sub Module:<span class="text-danger">*</span></label>
<div class="form-group">
<Dropdown name="subModuleId" v-model="subModuleId" :options="subModuleList"
optionLabel="text" placeholder="Select Sub Module" class="widthAll"
:editable="true" :filter="true" :showClear="true" />
</div>
</div>
</div>
<div class="col-md-6 col-lg-6 col-sm-12 col-xs-12">
<div class="mb-3">
<label class="form-label">Device Type:<span class="text-danger">*</span></label>
<div class="form-group">
<Dropdown name="deviceTypeId" v-model="deviceTypeId" :options="deviceTypeList"
optionLabel="text" placeholder="Select Device Type" class="widthAll"
:editable="true" :filter="true" />
</div>
</div>
</div>
<div class="col-md-6 col-lg-6 col-sm-12 col-xs-12">
<div class="mb-3">
<label class="form-label">Layout Type:<span class="text-danger">*</span></label>
<div class="form-group">
<Dropdown name="layoutTypeId" v-model="layoutTypeId" :options="layoutTypeList"
optionLabel="text" placeholder="Select Layout Type" class="widthAll"
:editable="true" :filter="true" />
</div>
</div>
</div>
<div class="col-md-12 col-lg-12">
<div class="mb-3">
<label class="form-label">Description:</label>
<div class="form-group">
<input type="text" name="description" v-model="description" class="form-control"
maxlength="50" placeholder="Enter description"
:class="{ 'is-invalid': descriptionError }" />
<div class="invalid-feedback">{{ descriptionError }}</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<div class="col-12 mt-3">
<button type="submit" class="btn btn-success me-2">Submit</button>
Cancel
</div>
</div>
</form>
</div>
</div>
</template>
<script>
import { ref, onMounted } from 'vue';
import * as Yup from 'yup';
import Dropdown from 'primevue/dropdown';
import InputMask from '#/views/shared/inputmask/inputmasktemplate.vue';
//Services
import CommonService from '#/service/crmservice/commonService';
import ManageLayoutService from '#/service/crmservice/manageLayoutService';
import { useForm, useField } from 'vee-validate';
export default {
name: 'ManageLayoutAddView',
components: {
InputMask,
Dropdown
},
props: {
isModalOpen: Yup.boolean
},
setup(props) {
console.log(props)
const commonService = ref(new CommonService());
const manageLayoutService = ref(new ManageLayoutService());
const layoutTypeKey = ref('layoutType');
const deviceTypeKey = ref('deviceType');
const moduleList = ref([]);
const subModuleList = ref([]);
const layoutTypeList = ref([]);
const deviceTypeList = ref([]);
const companyId = ref(null);
const userId = ref(null);
const layoutObj = ref({
layoutName: null,
moduleId: null,
subModuleId: null,
deviceTypeId: null,
layoutTypeId: null,
description: null,
});
const schema = Yup.object().shape({
layoutName: Yup.string().required('Layout Name is required'),
moduleId: Yup.string().required('Module is required'),
subModuleId: Yup.string().required('Sub Module is required'),
deviceTypeId: Yup.string().required('Device Type is required'),
layoutTypeId: Yup.string().required('Layout Type is required'),
description: Yup.string()
});
const { handleSubmit, errors, meta } = useForm({
validationSchema: schema,
});
const { value: layoutName, errorMessage: layoutNameError } = useField("layoutName");
const { value: moduleId, errorMessage: moduleIdError } = useField("moduleId");
const { value: subModuleId, errorMessage: subModuleIdError } = useField("subModuleId");
const { value: deviceTypeId, errorMessage: deviceTypeIdError } = useField("deviceTypeId");
const { value: layoutTypeId, errorMessage: layoutTypeIdError } = useField("layoutTypeId");
const { value: description, errorMessage: descriptionError } = useField("description");
const getMasterItemList = (masterKey) => {
// $loader.show();
commonService.value.getMasterItemList(masterKey, "asd", userId.value, companyId.value)
.then(response => {
masterKey == "layoutType" ? layoutTypeList.value = response.data : deviceTypeList.value = response.data;
// $loader.hide();
});
}
const getModuleList = () => {
// $loader.show();
commonService.value.getModuleList(userId.value, companyId.value)
.then(response => {
moduleList.value = response.data;
// $loader.hide();
})
}
const getSubModuleList = (moduleId) => {
// $loader.show();
commonService.value.getSubModuleList(moduleId, userId.value, companyId.value)
.then(response => {
subModuleList.value = response.data;
// $loader.hide();
})
}
const onChangeModule = (event) => {
getSubModuleList(event.value);
}
const getUserInfo = () => {
userId.value = localStorage.getItem("userId");
companyId.value = localStorage.getItem("companyId");
}
const onSubmit = handleSubmit((values) => {
debugger;
console.log(JSON.stringify(values, null, 2));
});
onMounted(() => {
getUserInfo();
getModuleList();
getMasterItemList(layoutTypeKey.value);
getMasterItemList(deviceTypeKey.value);
})
return {
layoutObj,
deviceTypeList,
layoutTypeList,
moduleList,
subModuleList,
errors,
meta,
layoutName, layoutNameError,
moduleId, moduleIdError,
subModuleId, subModuleIdError,
deviceTypeId, deviceTypeIdError,
layoutTypeId, layoutTypeIdError,
description, descriptionError,
getMasterItemList,
getModuleList,
onChangeModule,
onSubmit
}
}
}
</script>

Can't validate email with Vuelidate in Vue3

I'm trying to use validation option in a form. The app is developing under Vue3.
I have installed npm install #vuelidate/core #vuelidate/validator into project folder. In a file main.js I have been trying to add Vuelidate as following:
import { createApp } from 'vue'
import Vuelidate from 'vuelidate'
import App from './App.vue'
import './registerServiceWorker'
import router from './router'
import store from './store'
import 'materialize-css/dist/js/materialize.min'
createApp(App).use(store).use(router).use(Vuelidate).mount('#app')
Next I am working on Login.vue file as following
<template>
<form class="card auth-card" #submit.prevent="onSubmit">
<div class="card-content">
<span class="card-title">Example</span>
<div class="input-field">
<input
id="email"
type="text"
v-model.trim="email"
:class="{invalid: ($v.email.$dirty && !$v.email.required) || ($v.email.$dirty && !$v.email.email)}"
>
<label for="email">Email</label>
<small class="helper-text invalid"
v-if="$v.email.$dirty && !$v.email.required"
>Could not be empty</small>
<small class="helper-text invalid"
v-else-if="$v.email.$dirty && !$v.email.email"
>Incorrect form</small>
</div>
</div>
<div class="card-action">
<div>
<button
class="btn waves-effect waves-light auth-submit"
type="submit">
Enter-login
<i class="material-icons right">send</i>
</button>
</div>
</div>
</form>
</template>
<script>
import { email, required, minLength } from '#vuelidate/validators'
import useVuelidate from '#vuelidate/core'
export default {
name: 'login',
setup () {
return { v$: useVuelidate() }
},
data: () => ({
email: '',
password: ''
}),
validations: {
email: { email, required },
password: { required, minLength: minLength(6) }
},
methods: {
onSubmit () {
if (this.$v.$invalid) {
this.$v.$touch()
return
}
this.$router.push('/')
}
}
}
</script>
Then I try to run all that with npm run serve but with no success. Chrome DeveloperTools inform me about "Uncaught (in promise) TypeError: Cannot read property 'super' of undefined".
What did I do wrong? Is it possible to use Vue3 and Vuelidate together?
Lidia
Step 1: Import useVuelidate inside component
import useVuelidate from "#vuelidate/core";
import { email, required, minLength } from "#vuelidate/validators";
Step 2: Initalize useVuelidate inside component
setup() {
return { v$: useVuelidate() };
},
Step 3: Initalize your modal data
data() {
return {
email: '',
password: ''
};
},
Step 4: Add validations rule
validations() {
return {
email: { email, required },
password: { required, minLength: minLength(6) }
};
},
Step 5: Add form submit method
methods: {
onSubmit: function() {
this.v$.$touch();
if (this.v$.$error) return;
alert('Form is valid')
}
}
Step 6: HTML template design will be like,
<form class="card auth-card" #submit.prevent="onSubmit">
<div class="card-content">
<span class="card-title">Example</span>
<div class="input-field">
<label for="email">Email <span class="required">*</span></label>
<input id="email" type="text" v-model.trim="email">
<small class="error" v-for="(error, index) of v$.email.$errors" :key="index">
{{ capitalizeFirstLetter(error.$property) }} {{error.$message}}
</small>
</div>
<div class="input-field">
<label for="email">Password <span class="required">*</span></label>
<input id="email" type="text" v-model.trim="password">
<small class="error" v-for="(error, index) of v$.password.$errors" :key="index">
{{ capitalizeFirstLetter(error.$property) }} {{error.$message}}
</small>
</div>
</div>
<div class="card-action">
<div>
<button class="btn waves-effect waves-light auth-submit" type="submit"> Enter-login<i class="material-icons right">send</i>
</button>
</div>
</div>
</form>
</template>
DEMO

How to Send Foreign key id along with Form data in angular?

I'mm creating an Angular application with ASP.NET.
I need to create:
courses,
course contents
course schedules for the selected course.
After creating the course I will select that particular course and create the content for that.
But while submitting the form, I also need to save the selected course id as a foreign key in database.
Can anyone help me on this please?
createcontent.component.ts
import { Component, OnInit, EventEmitter, Output } from '#angular/core';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
import { CoursesService } from 'src/app/shared/courses.service';
import { Content } from '#angular/compiler/src/render3/r3_ast';
import {ActivatedRoute} from '#angular/router';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-createcontent',
templateUrl: './createcontent.component.html',
styleUrls: ['./createcontent.component.css']
})
export class CreatecontentComponent implements OnInit {
contentForm: FormGroup;
contents:Content[];
courseName: string;
courseid;
isSubmitted:boolean;
constructor(private courseservice:CoursesService,private fb: FormBuilder,private route:ActivatedRoute,private http:HttpClient) {
}
setValue(){
this.contentForm.setValue({
courseid:this.route.snapshot.params['id']
});
}
ngOnInit(): void {
this.courseName=this.route.snapshot.params['cname'];
this.courseid=this.route.snapshot.params['id']
this.contentForm = this.fb.group({
contentname: ['', Validators.required ],
contentdescription: ['', Validators.required ],
duration: ['', Validators.required ],
courseid:['']
});
this.courseservice
.getContents()
.subscribe((data: Content[]) => {
this.contents = data;
});
}
OnSubmit(){
console.log(this.contentForm);
this.http.post('https://localhost:44319/api/contents1',this.contentForm.value,this.courseid).subscribe(data=>{
console.log(data);
})
}
}
createtraining.component.ts
import { Component, OnInit, Input } from '#angular/core';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
import { CoursesService } from 'src/app/shared/courses.service';
import { Course } from 'src/app/shared/course.model';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-createtraining',
templateUrl: './createtraining.component.html',
styleUrls: ['./createtraining.component.css']
})
export class CreatetrainingComponent implements OnInit {
courseForm: FormGroup;
courses: Course[];
loading:false;
toggleState:boolean= false;
coursename = 'angular';
clickedCourse:string;
dayFinished:boolean=true;
constructor(private courseservice:CoursesService,private fb: FormBuilder,private http:HttpClient) {
}
getCourse(course:string){
this.clickedCourse=course;
}
ngOnInit(): void {
this.courseForm = this.fb.group({
coursename: ['', Validators.required ],
coursedescription: ['', Validators.required ]
});
this.courseservice
.getCourses()
.subscribe((data: Course[]) => {
this.courses = data;
this.toggleState=true;
});
}
OnSubmit(){
console.log(this.courseForm);
this.http.post('https://localhost:44319/api/courses',this.courseForm.value).subscribe(data=>{
console.log(data);
})
}
}
cretecontent.component.html
<div id="training-page" class="row">
<div class="col s8 offset-s2">
<div class="card">
<div class="sm-jumbotron center-align">
<h2>Create Content for {{courseName}}</h2>
</div>
</div>
<div class="card">
<form [formGroup]="contentForm" novalidate (ngSubmit)="OnSubmit()">
<div class="row"></div>
<div class="input-field col s6">
<input name="course_name" id="register-firstname" formControlName="contentname" type="text" class="form-input form-control" #contentname>
<label for="course_name" class="center-align">Topic Name<span class="required">*</span></label>
<div *ngIf="contentForm.controls['contentname'].invalid && (contentForm.controls['contentname'].dirty || contentForm.controls['contentname'].touched)">
<div *ngIf="contentForm.controls['contentname'].errors.required" style="color: red;font-size: 11px;">
Topic Name is required.
</div>
</div>
</div>
<div class="input-field col s6">
<input name="coursedesc" id="course-description" type="text" formControlName="contentdescription" class="form-input form-control" #contentdescription>
<label for="course_description" class="center-align">Topic Description<span class="required">*</span></label>
<div *ngIf="contentForm.controls['contentdescription'].invalid && (contentForm.controls['contentdescription'].dirty || contentForm.controls['contentdescription'].touched)">
<div *ngIf="contentForm.controls['contentdescription'].errors.required" style="color: red;font-size: 11px;">
Topic Description is required.
</div>
</div>
</div>
<div class="input-field col s6">
<input name="contenttime" id="course-description" type="text" formControlName="duration" class="form-input form-control" #duration>
<label for="course_description" class="center-align">Duration<span class="required">*</span></label>
<div *ngIf="contentForm.controls['duration'].invalid && (contentForm.controls['duration'].dirty || contentForm.controls['duration'].touched)">
<div *ngIf="contentForm.controls['duration'].errors.required" style="color: red;font-size: 11px;">
Duration is required.
</div>
</div>
</div>
<input type="text" id="courseid" formControlName="courseid" class="form-input form-control" #courseid>
<div class="row">
<div class="input-field col s12 valign center">
<button [disabled]="!contentForm.valid" (click)="setValue()" type="submit" class="btn-primary">Create</button>
</div>
</div>
</form>
</div>
<table class="table">
<thead class="thead-light">
<tr>
<th scope="col">Topic Name</th>
<th scope="col">Topic Description</th>
<th scope="col">Duration</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let content of contents">
<td>{{ content.contentname }}</td>
<td>{{ content.contentdescription }}</td>
<td>{{ content.duration}}</td>
</tr>
</tbody>
</table>
<div class="row">
<div class="input-field col s12 valign center">
<button type="button" class="btn-primary" [routerLink]="['/trainer']">Back to Course</button>
</div>
</div>
</div>

Gatsby: CSS by className only sometimes works [duplicate]

I'm almost new to react.
I'm trying to create a simple editing and creating mask.
Here is the code:
import React, { Component } from 'react';
import Company from './Company';
class CompanyList extends Component {
constructor(props) {
super(props);
this.state = {
search: '',
companies: props.companies
};
}
updateSearch(event) {
this.setState({ search: event.target.value.substr(0,20) })
}
addCompany(event) {
event.preventDefault();
let nummer = this.refs.nummer.value;
let bezeichnung = this.refs.bezeichnung.value;
let id = Math.floor((Math.random()*100) + 1);
$.ajax({
type: "POST",
context:this,
dataType: "json",
async: true,
url: "../data/post/json/companies",
data: ({
_token : window.Laravel.csrfToken,
nummer: nummer,
bezeichnung : bezeichnung,
}),
success: function (data) {
id = data.Nummer;
this.setState({
companies: this.state.companies.concat({id, nummer, bezeichnung})
})
this.refs.bezeichnung.value = '';
this.refs.nummer.value = '';
}
});
}
editCompany(event) {
alert('clicked');
event.preventDefault();
this.refs.bezeichnung.value = company.Bezeichnung;
this.refs.nummer.value = company.Nummer;
}
render() {
let filteredCompanies = this.state.companies.filter(
(company) => {
return company.bezeichnung.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1;
}
);
return (
<div>
<div className="row">
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">Suche</div>
<div className="col-xs-12 col-sm-12 col-md-9 col-lg-9">
<div className="form-group">
<input className="form-control" type="text" value={this.state.search} placeholder="Search" onChange={this.updateSearch.bind(this)} />
</div>
</div>
</div>
<form onSubmit={this.addCompany.bind(this)}>
<div className="row">
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">Neuen Eintrag erfassen</div>
<div className="col-xs-12 col-sm-12 col-md-3 col-lg-3">
<div className="form-group">
<input className="form-control" type="text" ref="nummer" placeholder="Nummer" required />
</div>
</div>
<div className="col-xs-12 col-sm-12 col-md-3 col-lg-3">
<div className="form-group">
<input className="form-control" type="text" ref="bezeichnung" placeholder="Firmenname" required />
</div>
</div>
<div className="col-xs-12 col-sm-12 col-md-3 col-lg-3">
<div className="form-group">
<button type="submit" className="btn btn-default">Add new company</button>
</div>
</div>
</div>
</form>
<div className="row">
<div className="col-xs-10 col-sm-10 col-md-10 col-lg-10">
<ul>
{
filteredCompanies.map((company)=> {
return <Company company={company} key={company.id} onClick={this.editCompany.bind(this)} />
})
}
</ul>
</div>
</div>
</div>
);
}
}
export default CompanyList
The Company class looks like this:
import React, { Component } from 'react';
const Company = ({company}) =>
<li>
{company.Nummer} {company.Bezeichnung}
</li>
export default Company
My question now is, why is the onclick event not being fired, when I click on a Company.
In this part:
<ul>
{
filteredCompanies.map((company)=> {
return <Company company={company} key={company.id} onClick={this.editCompany.bind(this)} className="Company"/>
})
}
</ul>
The reason is pretty simple, when you onClick like
<Company company={company} key={company.id} onClick={this.editCompany.bind(this)} />
its not an event that is set on the component, rather a prop that is being passed to the Company component and can be accessed like props.company in the Company component,
what you need to do is to specify the onClick event and className in the Company component like
import React, { Component } from 'react';
const Company = ({company, onClick, className}) => (
<li onClick={onClick} className={className}>
{company.Nummer} {company.Bezeichnung}
</li>
)
export default Company
The function passed on as prop to the Company component can be passed on by any name like
<Company company={company} key={company.id} editCompany={this.editCompany.bind(this)} className="Company"/>
and used like
import React, { Component } from 'react';
const Company = ({company, editCompany}) => (
<li onClick={editCompany}>
{company.Nummer} {company.Bezeichnung}
</li>
)
you have to bind the event on you child component :
import React, { Component } from 'react';
const Company = ({ company, onClick }) =>
<li onClick={onClick}>
{company.Nummer} {company.Bezeichnung}
</li>
export default Company
or
const Company = ({ company, ...props }) =>
<li {...props}>
{company.Nummer} {company.Bezeichnung}
</li>
if you want that all props passed to your Compagny component (exept compagny) goes to your li tag. see ES6 spread operator and rest.

Angular firebase upload images

I am a beginner working with Angular 5 and firebase.
As practice I decided to create a blog.
My problem is that I can not upload my images in firestore. When I upload to Cloud storage and try to retrieve the download link, it does not register in firestore.
Take a look at my code and give me suggestions.
import { Component, OnInit } from '#angular/core';
import { AuthService } from 'src/app/shared/services/auth.service';
import { finalize } from 'rxjs/operators';
import { Observable } from 'rxjs';
import { AngularFireStorage } from '#angular/fire/storage';
import { PostsService } from 'src/app/shared/services/posts.service';
import { ToastrService } from 'ngx-toastr';
import { Router } from '#angular/router';
#Component({
selector: 'app-posts',
templateUrl: './posts.component.html',
styleUrls: ['./posts.component.scss']
})
export class PostsComponent implements OnInit {
uploadPercent: Observable<number>;
downloadURL: Observable<string>;
title: string;
content: string;
description: string;
image: string = null;
constructor(private auth: AuthService,
private toast: ToastrService,
private postService: PostsService,
private store: AngularFireStorage,
private router: Router) { }
ngOnInit() {
}
createPost() {
// tslint:disable-next-line:prefer-const
let data = {
content: this.content,
image: this.image,
description: this.description,
publication: new Date(),
title: this.title
};
this.router.navigate(['/admin']);
this.postService.create(data);
this.title = '';
this.description = '';
this.content = '';
this.toast.success('Votre article a été publié');
}
uploadImage(event) {
// tslint:disable-next-line:prefer-const
let file = event.target.files[0];
// tslint:disable-next-line:prefer-const
let path = `posts/${file.name}`;
if (file.type.split('/')[0] !== 'image') {
return alert('Erreur, ce fichier n\'est pas une image');
} else {
// tslint:disable-next-line:prefer-const
let ref = this.store.ref(path);
// tslint:disable-next-line:prefer-const
let task = this.store.upload(path, file);
this.uploadPercent = task.percentageChanges();
console.log('Image chargée avec succès');
task.snapshotChanges().pipe(
finalize(() => {
this.downloadURL = ref.getDownloadURL();
this.downloadURL.subscribe(url => {
console.log(url);
});
}
)
).subscribe();
}
}
}
<div class="col-8">
<div class="input-group mb-3">
<div class="custom-file">
<input type="file" class="custom-file-input" id="inputGroupFile03" aria-describedby="inputGroupFileAddon03" (change)="uploadImage($event)" accept=".png,.jpg" [(ngModel)]="image">
<label class="custom-file-label" for="inputGroupFile03">Choisir une image</label>
</div>
</div>
<div class="progress" [hidden]="!uploadPercent">
<mat-progress-bar mode="determinate" value="{{ uploadPercent | async }}"></mat-progress-bar>
{{ uploadPercent | async }}
</div>
<div [hidden]="!image">
<img [src]="image || '//:0'">
</div>
<div class="form-group">
<label for="title"> Titre du post </label>
<input type="text" class="form-control" name="title" id="title" placeholder="Titre" required [(ngModel)]="title"/>
</div>
<div class="form-group">
<label for="description"> Description </label>
<input type="text" class="form-control" name="description" id="description" placeholder="Desciption"
data-toggle="tooltip" data-placement="top" title="Ajouter une breve description de l'article" required [(ngModel)]="description"/>
</div>
<div class="form-group">
<label for="content"> Contenu de l'artcle </label>
<textarea class="form-control" name="content" id="content" cols="15" rows="5" placeholder="..." required [(ngModel)]="content"></textarea>
</div>
<button class="btn btn-success btn-lg btn-block" (click)="createPost()">Poster l'article <i class="fa fa-paper-plane"
aria-hidden="true"></i>
</button>
</div>
enter image description here

Resources