Angular 2 and ng2-file-upload - django

I am re writing an application into Angular and have to upload a file. The network shows me status: 200 but there is no response and my back end is not receiving any file.
Why Request Method is OPTION and CORS(in chrome) ?
Chrome:
chrome console: Response to preflight request doesn't pass access control check: Credentials flag is 'true', but the 'Access-Control-Allow-Credentials' header is ''. It must be 'true' to allow credentials. Origin is therefore not allowed access.
enter image description here
Firefox:
firefox not has consol error
enter image description here
My cod:
import { Component, OnInit } from '#angular/core';
import { FileUploader } from 'ng2-file-upload';
const URL = 'http://127.0.0.1:8000/api/v1/upload/';
#Component({
selector: 'app-upload',
templateUrl: './upload.component.html',
styleUrls: ['./upload.component.css']
})
export class UploadComponent implements OnInit {
public uploader: FileUploader;
constructor()
{
this.initUpload()
}
ngOnInit() {
}
initUpload() {
this.uploader = new FileUploader({
url: URL,
method: 'POST',
headers: [
{name: 'Access-Control-Allow-Credentials', value: 'true'},
{name:'Access-Control-Allow-Origin', value: '*'}
]
});
}
}
--------------------------------------------
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { FileUploadModule } from 'ng2-file-upload';
import { AppComponent } from './app.component';
import { UploadComponent } from './upload/upload.component';
#NgModule({
imports: [
BrowserModule,
FormsModule,
HttpModule,
FileUploadModule
],
declarations: [
AppComponent,
UploadComponent,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
--------------------------------------------
<input type="file" ng2FileSelect [uploader]="uploader" multiple /><br/>
<table class="table">
<thead>
<tr>
<th width="50%">Name</th>
<th>Size</th>
<th>Progress</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of uploader.queue">
<td><strong>{{ item.file.name }}</strong></td>
<td nowrap>{{ item.file.size/1024/1024 | number:'.2' }} MB</td>
<td>
<div class="progress" style="margin-bottom: 0;">
<div class="progress-bar" role="progressbar" [ngStyle]="{ 'width': item.progress + '%' }"></div>
</div>
</td>
<td class="text-center">
<span *ngIf="item.isSuccess"><i class="glyphicon glyphicon-ok"></i></span>
<span *ngIf="item.isCancel"><i class="glyphicon glyphicon-ban-circle"></i></span>
<span *ngIf="item.isError"><i class="glyphicon glyphicon-remove"></i></span>
</td>
<td nowrap>
<button type="button" class="btn btn-success btn-xs"
(click)="item.upload()" [disabled]="item.isReady || item.isUploading || item.isSuccess">
<span class="glyphicon glyphicon-upload"></span> Upload
</button>
<button type="button" class="btn btn-warning btn-xs"
(click)="item.cancel()" [disabled]="!item.isUploading">
<span class="glyphicon glyphicon-ban-circle"></span> Cancel
</button>
<button type="button" class="btn btn-danger btn-xs"
(click)="item.remove()">
<span class="glyphicon glyphicon-trash"></span> Remove
</button>
</td>
</tr>
</tbody>
</table>
django using
CORS_ORIGIN_WHITELIST = (
'localhost:4200'
)

I think the problem is for calling localhost from google chrome
As simple solution you can install CORS extension to all access -origin
You can install it from here
Also you can add these headers in your API response
'Access-Control-Allow-Origin', 'http://mysite')
'Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
'Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');

Related

How do make ASP.NET React JS template usable?

I have followed a Microsoft template to get an ASP.NET Core React JS project in visual studio 2022. The end product displays a list of weather forecasts with no navigability in the website. I am trying to convert the site to be more adaptable and start building my own project. I have attached a navbar file that I would like to implement, and the removal of the weather forecast. Please can someone tell me how to do this?
App.js
import React, { Component } from 'react';
import "bootstrap/dist/css/bootstrap.min.css";
import Navbar from './Navigation/Navbar.js';
export default class App extends Component {
static displayName = App.name;
constructor(props) {
super(props);
this.state = { forecasts: [], loading: true };
}
componentDidMount() {
this.populateWeatherData();
}
static renderForecastsTable(forecasts) {
return (
<table className='table table-striped' aria-labelledby="tabelLabel">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
{forecasts.map(forecast =>
<tr key={forecast.date}>
<td>{forecast.date}</td>
<td>{forecast.temperatureC}</td>
<td>{forecast.temperatureF}</td>
<td>{forecast.summary}</td>
</tr>
)}
</tbody>
</table>
);
}
render() {
let contents = this.state.loading
? <p><em>Loading... Please refresh once the ASP.NET backend has started. See https://aka.ms/jspsintegrationreact for more details.</em></p>
: App.renderForecastsTable(this.state.forecasts);
return (
<div>
<h1 id="tabelLabel" >Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
{contents}
</div>
);
}
async populateWeatherData() {
const response = await fetch('weatherforecast');
const data = await response.json();
this.setState({ forecasts: data, loading: false });
}
}
Index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
reportWebVitals();
Navbar.js
import React from "react";
const Navbar = () => {
return (
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<a className="navbar-brand" href="#">
Navbar
</a>
<button
className="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbarNavDropdown"
aria-controls="navbarNavDropdown"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarNavDropdown">
<ul className="navbar-nav">
<li className="nav-item active">
<a className="nav-link" href="#">
Home <span className="sr-only">(current)</span>
</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#">
Features
</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#">
Pricing
</a>
</li>
<li className="nav-item dropdown">
<a
className="nav-link dropdown-toggle"
href="#"
id="navbarDropdownMenuLink"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
Dropdown link
</a>
<div
className="dropdown-menu"
aria-labelledby="navbarDropdownMenuLink"
>
<a className="dropdown-item" href="#">
Action
</a>
<a className="dropdown-item" href="#">
Another action
</a>
<a className="dropdown-item" href="#">
Something else here
</a>
</div>
</li>
</ul>
</div>
</nav>
);
};
export default Navbar;

Template Parse Erros Angular "<" (" with Django REST framework

I've been trying to create a DRF API with an Angular front end for an existing project that I have. I've created a serializer for User and Device. I tried removing multiple pieces of the HTML component, managing to result in a different error, StaticInjectorError(AppModule -> DevicePostService).
I'm still pretty new to Angular so what it seems like the error is coming from is the fact that my devicepostservice is not getting served to the web page for some reason.
Console error:
[Error] Error: Template parse errors:
Unexpected character "<" ("
<div class="col-sm-4">
<button (click)="login()" class="btn btn-primary">Log In</button
[ERROR ->]</div>
<div class="col-sm-12">
<span *ngFor="let error of _userService.errors.non_field_errors""): ng:///AppModule/AppComponent.html#15:2
Unexpected closing tag "div". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags ("
<div class="col-sm-4">
<button (click)="login()" class="btn btn-primary">Log In</button
[ERROR ->]</div>
<div class="col-sm-12">
<span *ngFor="let error of _userService.errors.non_field_errors""): ng:///AppModule/AppComponent.html#15:2
Unexpected closing tag "div". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags (" <span *ngFor="let error of _userService.errors.non_field_errors">{{ error }}<br /></span>
</div>
[ERROR ->]</div>
<div class="row" *ngIf="_userService.token">
<div class="col-sm-12">You are logged in as {{ "): ng:///AppModule/AppComponent.html#19:0
_preparseLoadedTemplate (vendor.js:24658)
normalizeTemplate (vendor.js:24635)
loadDirectiveMetadata (vendor.js:26827)
(anonymous function) (vendor.js:34471)
forEach
(anonymous function) (vendor.js:34470)
forEach
_loadModules (vendor.js:34467:83)
_compileModuleAndComponents (vendor.js:34445)
compileModuleAsync (vendor.js:34405)
bootstrapModule (vendor.js:53721)
./src/main.ts (main.js:326:116)
__webpack_require__ (runtime.js:79)
(anonymous function) (main.js:339)
__webpack_require__ (runtime.js:79)
checkDeferredModules (runtime.js:46)
webpackJsonpCallback (runtime.js:33)
Global Code (main.js:1)
App.component.html
<h2>Log In</h2>
<div class="row" *ngIf="!_userService.token">
<div class="col-sm-4">
<label>Username:</label><br />
<input type="text" name="login-username" [(ngModel)]="user.username">
<span *ngFor="let error of _userService.errors.username"><br />
{{ error }}</span></div>
<div class="col-sm-4">
<label>Password:</label><br />
<input type="password" name="login-password" [(ngModel)]="user.password">
<span *ngFor="let error of _userService.errors.password"><br />
{{ error }}</span>
</div>
<div class="col-sm-12">
<span *ngFor="let error of _userService.errors.non_field_errors">{{ error }}<br /></span>
</div>
</div>
<div class="row" *ngIf="_userService.token">
<div class="col-sm-12">You are logged in as {{ _userService.username }}.<br />
Token Expires: {{ _userService.token_expires }}<br />
<button (click)="refreshToken()" class="btn btn-primary">Refresh Token</button>
<button (click)="logout()" class="btn btn-primary">Log Out</button>
</div>
</div>
<!--
<h2 class="mt-3">Devices</h2>
<div *ngFor="let device of devices">
<div class="row mb-3">
<label class="col-md-2">Owner:</label>
<div class="col-md-2 mb-1">{{ device.owner }}</div>
<label class="col-md-2">Brand:</label>
<div class="col-md-6">{{ device.brand }}</div>
<div class="col-md-12">{{ device.name }}</div>
</div>
</div>-->
App.component.ts
import {Component, OnInit} from '#angular/core';
import {DevicePostService} from './device_post.service';
import {UserService} from './user.service';
import {throwError} from 'rxjs';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
/**
* An object representing the user for the login form
*/
public user: any;
public devices;
public new_device: any;
constructor(private _devicePostService: DevicePostService, private _userService: UserService) { }
ngOnInit() {
this.getDevices();
this.new_device = {};
this.user = {
username: '',
password: ''
};
}
getDevices() {
this._devicePostService.list().subscribe(
data => {
this.devices = data;
},
err => console.error(err),
() => console.log('done loading devices')
)
}
updateDevice () {
this._devicePostService.create(this.new_device, this.user.token).subscribe(
data => {
this.getDevices();
return true;
},
error => {
console.error('Error saving!');
return throwError(error);
}
);
}
login() {
this._userService.login({'username': this.user.username, 'password': this.user.password});
}
refreshToken() {
this._userService.refreshToken();
}
logout() {
this._userService.logout();
}
}
Seems like you have a basic syntax error in your template
<button (click)="login()" class="btn btn-primary">Log In</button
should be
<button (click)="login()" class="btn btn-primary">Log In</button>
(note the final '>' character)

Angular 2 View not displaying data from Webservice

I have a Web Service which is providing some user data (this is Java backend) and I have an Angular component:
import { Component,state,style,animate,transition, trigger, keyframes,
OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/pluck';
import { IUser } from './user.interface';
#Component({
moduleId: module.id,
selector: 'user-cmp',
templateUrl: 'user.component.html'
})
export class UserComponent {
user: Observable<IUser>;
errorMessage: string;
constructor(private _userService: ActivatedRoute){
this.user = _userService.data.pluck('user');
}
}
I am using a Resolver:
import { Resolve } from '#angular/router';
import { Observable } from 'rxjs/Observable'
import { Observer } from 'rxjs/Observer';
import { IUser } from './user.interface';
import { UserService } from './user.service';
import {Injectable} from "#angular/core";
#Injectable()
export class UsersResolver implements Resolve<IUser> {
constructor (private _userService: UserService) {}
resolve(): Observable<IUser>{
return this._userService.getUser();
}
}
Resolver is using a service:
import {Injectable} from "#angular/core";
import { Http, Response } from "#angular/http";
import { IUser } from './user.interface';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
#Injectable()
export class UserService {
private _userUrl = 'http://localhost:8000/rest/users';
constructor(private _http: Http){
}
getUser(): Observable<IUser>{
return this._http.get(this._userUrl)
.map((response: Response) => {
return <IUser> response.json();
})
.do(data => console.log('All: ' + JSON.stringify(data)))
.catch(this.handleError);
}
private handleError (error: Response){
console.error(error);
return Observable.throw(error.json().error || 'Server Error');
}
}
And finally the View:
<div class="main-content" >
<div class="container-fluid">
<div class="row">
<div class="col-md-8">
<div class="card" [#carduserprofile]>
<div class="header">
<h4 class="title">Edit User Profile</h4>
</div>
<div *ngIf="user" class="content">
<form>
<div class="row">
<div class="col-md-3">
<div class="form-group">
<label>Username</label>
<input type="text" class="form-control" placeholder="Username" value="{{user.username }}">
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label>Email address</label>
<input type="email" class="form-control" placeholder="Email" value="{{user.password}}">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Phone</label>
<input type="text" class="form-control" placeholder="Phone" value="{{user.telephone}}">
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Type</label>
<input type="text" class="form-control" disabled placeholder="User type" value="{{user.type}}">
</div>
</div>
</div>
<button type="submit" class="btn btn-info btn-fill pull-right">Update Profile</button>
<div class="clearfix"></div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
The module looks like this:
import { NgModule } from '#angular/core';
import { RouterModule } from '#angular/router';
import { BrowserModule } from '#angular/platform-browser';
import { MODULE_COMPONENTS, MODULE_ROUTES } from './dashboard.routes';
import { UsersResolver } from './user/user.resolver';
#NgModule({
imports: [
BrowserModule,
RouterModule.forChild(MODULE_ROUTES)
],
declarations: [ MODULE_COMPONENTS ],
providers: [ UsersResolver ]
})
export class DashboardModule{}
And also the part of the route is like this:
{ path: 'user', component: UserComponent, resolve: {user: UsersResolver} },
I didn't paste some useless parts of the code, like animations and etc.
My problem is, it prints the data from the webservide using the .do in the service, but it doesn't show nothing in the View. Fields are blank.
I am using *ngIf in case of blank user data from WS.
I have no idea why and also I don't know how to implement some codes to check it in the View.
Any help will be great!
Thanks in advance.
The problem I see is located here:
constructor(private _userService: ActivatedRoute){
this.user = _userService.data.pluck('user');
}
this.user is an observable so you need to subscribe it to get the value either within the component (with this.user.subscribe(...)) or in the template using the async pipe.
Perhaps you could simply leverage the snapshot for the route:
constructor(private _userService: ActivatedRoute){
this.user = _userService.snapshot.data['user'];
}
This way the user would be a raw JS object and not an observable. So using the following should be better:
<div *ngIf="user" class="content">

Vue.js For loop is not rendering content

I am building a web application using vue.js, vue-resource, vue-mdl and google material design lite.
JS compilation is performed using webpack through laravel elixir.
In this app I have to render a table row for each object from an array returned from a Rest API (Django Rest Framework). I have made the following code inside the html to render content using vue.js:
<tr v-for="customer in customers">
<td class="mdl-data-table__cell--non-numeric">{{ customer.status }}</td>
<td class="mdl-data-table__cell--non-numeric">{{ customer.name }}</td>
<td class="mdl-data-table__cell--non-numeric">{{ customer.company }}</td>
<tr>
This should render all objects in the array as a table row. I have also tried to wrap the above in a template tag like this:
<template v-for="customer in customers">
<tr>
<td class="mdl-data-table__cell--non-numeric">{{ customer.status }}</td>
<td class="mdl-data-table__cell--non-numeric">{{ customer.name }}</td>
<td class="mdl-data-table__cell--non-numeric">{{ customer.company }}</td>
</tr>
</template>
This did not change either.
I have also tried to hardcode the array inside the ready() function of the vue instance, but this did not help either.
window._ = require('lodash');
require('material-design-lite');
window.Vue = require('vue');
require('vue-resource');
var VueMdl = require('vue-mdl');
Vue.use(VueMdl.default);
const app = new Vue({
el:'body',
ready: function(){
//this.getCustomerList();
this.customers = [
{ name: "Peter", status: "true", company: "Company 1"},
{ name: "John", status: "false", company: "Company 2"}
]
},
data: {
customers: [],
response: null,
messages: []
},
methods: {
getCustomerList: function()
{
this.$http({url: '/api/customers/', method: 'GET'}).then(function(response){
//Success
this.customers = response.data
console.log(response.data)
},
function(response){
console.log(response)
})
}
}
})
Changing the above to this does not change either:
window._ = require('lodash');
require('material-design-lite');
window.Vue = require('vue');
require('vue-resource');
var VueMdl = require('vue-mdl');
Vue.use(VueMdl.default);
const app = new Vue({
el:'body',
ready: function(){
//this.getCustomerList();
},
data: {
customers: [
{ name: "Peter", status: "true", company: "Company 1"},
{ name: "John", status: "false", company: "Company 2"}
],
response: null,
messages: []
},
methods: {
getCustomerList: function()
{
this.$http({url: '/api/customers/', method: 'GET'}).then(function(response){
//Success
this.customers = response.data
console.log(response.data)
},
function(response){
console.log(response)
})
}
}
})
I have also tried to just make a plain html table that does not have any of the Google MDL classes applied, and this does also not give any result.
Logging this.customers to the console shows that it does in fact contain the data, but for reason it is not rendering. Why is that? What am I doing wrong?
Here's a snippet of your code, which works as expected. I've added in CDN references to the libraries you mentioned, but I'm not doing anything with them. I offer this as a starting point for you to see if you can find what changes will reproduce your problem here.
const app = new Vue({
el: 'body',
ready: function() {
//this.getCustomerList();
this.customers = [{
name: "Peter",
status: "true",
company: "Company 1"
}, {
name: "John",
status: "false",
company: "Company 2"
}]
},
data: {
customers: [],
response: null,
messages: []
}
})
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/vue-resource/0.9.3/vue-resource.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://code.getmdl.io/1.2.0/material.indigo-pink.min.css">
<script defer src="https://code.getmdl.io/1.2.0/material.min.js"></script>
<script src="https://rawgit.com/posva/vue-mdl/develop/dist/vue-mdl.min.js"></script>
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--3-col">
<button id="create-customer" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect" #click="$refs.createCustomer.open">
Create customer
</button>
</div>
<div class="mdl-cell mdl-cell--3-col">
<button id="convert-reseller" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect">
Convert to reseller
</button>
</div>
<div class="mdl-cell mdl-cell--3-col">
<button id="remove-customer" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect">
Remove Customer
</button>
</div>
<div class="mdl-cell mdl-cell--3-col">
<button id="change-status" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect">
Change status
</button>
</div>
</div>
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--12-col">
<table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable" style="width:100%;">
<thead>
<tr>
<th class="mdl-data-table__cell--non-numeric">Status</th>
<th class="mdl-data-table__cell--non-numeric">Customer name</th>
<th class="mdl-data-table__cell--non-numeric">Company</th>
</tr>
</thead>
<tbody>
<tr v-for="customer in customers">
<td class="mdl-data-table__cell--non-numeric">{{ customer.status }}</td>
<td class="mdl-data-table__cell--non-numeric">{{ customer.name }}</td>
<td class="mdl-data-table__cell--non-numeric">{{ customer.company }}</td>
</tr>
</tbody>
</table>
</div>
</div>
It seems now to be working.
Inside app.js I had:
const app = new Vue({ el: 'body' })
That, for some reason, conflicted with the one I was creating inside customer_list.js—although my methods worked fine.

Ember: Integrating Google Recaptcha with ember-cp-validations

I have a simple contact form, with validation done using ember-cp-validations https://github.com/offirgolan/ember-cp-validations and I now need to integrate the new Google Recaptcha into that.
For the rendering of the recaptcha, I am using this code - https://gist.github.com/cravindra/5beeb0098dda657433ed - which works perfectly.
However, I don't know how to deal with the verification process to allow the form to be submitted/prevented if the challenge is correct/incorrect or not provided
Here is a truncated version of my contact-form component
import Ember from 'ember';
import Validations from './cp-validations/contact-form';
import config from '../config/environment';
export default Ember.Component.extend(Validations,{
data:{},
nameMessage:null,
init() {
this._super(...arguments);
this.set('data',{});
},
actions:{
submitForm() {
this.validate().then(({model,validations}) => {
if (validations.get('isValid')) {
// submit form
}
else {
if(model.get('validations.attrs.data.name.isInvalid')){
this.set('nameMessage',model.get('validations.attrs.data.name.messages'));
}
}
})
}
}
});
Here is the template for the component, which includes the rendering of the recpatcha using the gist above
<form {{action 'submitForm' on='submit'}}>
<div class="row">
<div class="medium-6 columns">
{{input type="text" value=data.name id="name" placeholder="Enter your name"}}
<div class="error-message">
{{nameMessage}}
</div>
</div>
</div>
<div class="row">
<div class="medium-12 columns">
{{google-recaptcha}}
</div>
</div>
<button class="button primary" type="submit">Submit</button>
</form>
The Validations import looks like this
import { validator, buildValidations } from 'ember-cp-validations';
export default buildValidations({
'data.name': {
validators: [
validator('presence',{
presence:true,
message:'Please enter your name'
})
]
},
});
Many thanks for any help!
Register captchaComplete in your google-recaptcha component and mix the answer with your validations
UPDATE
contact-form.hbs
<form {{action 'submitForm' on='submit'}}>
<div class="row">
<div class="medium-6 columns">
{{input type="text" value=data.name id="name" placeholder="Enter your name"}}
<div class="error-message">
{{nameMessage}}
</div>
</div>
</div>
<div class="row">
<div class="medium-12 columns">
{{google-recaptcha captchaComplete=validateRecatcha}}
</div>
</div>
<button class="button primary" type="submit">Submit</button>
</form>
contact-form.js
import Ember from 'ember';
import Validations from './cp-validations/contact-form';
import config from '../config/environment';
export default Ember.Component.extend(Validations,{
data:{},
nameMessage:null,
captchaValidated: false,
init() {
this._super(...arguments);
this.set('data',{});
},
actions:{
validateRecatcha(data){
//if data denotes captcha is verified set captchaValidated to true else false
},
submitForm() {
this.validate().then(({model,validations}) => {
if (validations.get('isValid') && this.get('captchaValidated')) {
// submit form
}
else {
if(model.get('validations.attrs.data.name.isInvalid')){
this.set('nameMessage',model.get('validations.attrs.data.name.messages'));
}
}
})
}
}
});