App won't display all items (Ionic, Backand) - ionic-framework

I want to make an app which displays some items, so I found the backand template (https://market.ionic.io/starters/backand-simple) and used it. I have about 40 items in my database, but the app only displays the first 20 items.
my controller.js
angular.module('SimpleRESTIonic.controllers', [])
.controller('LoginCtrl', function (Backand, $state, $rootScope, LoginService) {
var login = this;
function signin() {
LoginService.signin(login.email, login.password)
.then(function () {
onLogin();
}, function (error) {
console.log(error)
})
}
function onLogin(){
$rootScope.$broadcast('authorized');
login.email = '';
login.password = '';
$state.go('tab.dashboard');
}
function signout() {
LoginService.signout()
.then(function () {
//$state.go('tab.login');
login.email = '';
login.password = '';
$rootScope.$broadcast('logout');
$state.go($state.current, {}, {reload: true});
})
}
login.signin = signin;
login.signout = signout;
})
.controller('DashboardCtrl', function (ItemsModel, $rootScope) {
var vm = this;
function goToBackand() {
window.location = 'http://docs.backand.com';
}
function getAll() {
ItemsModel.all()
.then(function (result) {
vm.data = result.data.data;
});
}
function clearData(){
vm.data = null;
}
function create(object) {
ItemsModel.create(object)
.then(function (result) {
cancelCreate();
getAll();
});
}
function update(object) {
ItemsModel.update(object.id, object)
.then(function (result) {
cancelEditing();
getAll();
});
}
function deleteObject(id) {
ItemsModel.delete(id)
.then(function (result) {
cancelEditing();
getAll();
});
}
function initCreateForm() {
vm.newObject = {name: '', description: ''};
}
function setEdited(object) {
vm.edited = angular.copy(object);
vm.isEditing = true;
}
function isCurrent(id) {
return vm.edited !== null && vm.edited.id === id;
}
function cancelEditing() {
vm.edited = null;
vm.isEditing = false;
}
function cancelCreate() {
initCreateForm();
vm.isCreating = false;
}
vm.objects = [];
vm.edited = null;
vm.isEditing = false;
vm.isCreating = false;
vm.getAll = getAll;
vm.create = create;
vm.update = update;
vm.delete = deleteObject;
vm.setEdited = setEdited;
vm.isCurrent = isCurrent;
vm.cancelEditing = cancelEditing;
vm.cancelCreate = cancelCreate;
vm.goToBackand = goToBackand;
vm.isAuthorized = false;
$rootScope.$on('authorized', function () {
vm.isAuthorized = true;
getAll();
});
$rootScope.$on('logout', function () {
clearData();
});
if(!vm.isAuthorized){
$rootScope.$broadcast('logout');
}
initCreateForm();
getAll();
});
my services.js
angular.module('SimpleRESTIonic.services', [])
.service('APIInterceptor', function ($rootScope, $q) {
var service = this;
service.responseError = function (response) {
if (response.status === 401) {
$rootScope.$broadcast('unauthorized');
}
return $q.reject(response);
};
})
.service('ItemsModel', function ($http, Backand) {
var service = this,
baseUrl = '/1/objects/',
objectName = 'items/';
function getUrl() {
return Backand.getApiUrl() + baseUrl + objectName;
}
function getUrlForId(id) {
return getUrl() + id;
}
service.all = function () {
return $http.get(getUrl());
};
service.fetch = function (id) {
return $http.get(getUrlForId(id));
};
service.create = function (object) {
return $http.post(getUrl(), object);
};
service.update = function (id, object) {
return $http.put(getUrlForId(id), object);
};
service.delete = function (id) {
return $http.delete(getUrlForId(id));
};
})
.service('LoginService', function (Backand) {
var service = this;
service.signin = function (email, password, appName) {
//call Backand for sign in
return Backand.signin(email, password);
};
service.anonymousLogin= function(){
// don't have to do anything here,
// because we set app token att app.js
}
service.signout = function () {
return Backand.signout();
};
});
my dashboard-tab //which displays the items
<ion-view view-title="Produkte">
<div ng-if="!vm.isCreating && !vm.isEditing">
<ion-content class="padding has-header">
<!-- LIST -->
<div class="bar bar-header bar-balanced">
<span ng-click="vm.isCreating = true"><i class='icon ion-plus-round new-item'> Erstellen</i></span>
</div>
<div class="bar bar-subheader">
<div class="list card" ng-repeat="object in vm.data"
ng-class="{'active':vm.isCurrent(object.id)}">
<div class="item item-icon-right item-icon-left">
<i class="ion-compose icon" ng-click="vm.setEdited(object)"></i>
<h2 class="text-center"><b>{{object.name}}</b></h2>
<i class="icon ion-close-round" ng-click="vm.delete(object.id)"></i>
</div>
<div class="text-center">
{{object.description}}
</div>
<div class="item item-body">
<p style="text-align:center;"><img src="{{object.imgurl}}" style="max-width: 250px; max-height: 250px" /></p>
</div>
<div class="text-center">
{{object.price}} Euro
</div>
</div>
</div>
</ion-content>
</div>
<div ng-if="vm.isCreating">
<ion-content class="padding has-header">
<!-- Erstellen -->
<div class="bar bar-header">
<h2 class="title">Erstelle ein Produkt</h2>
<span ng-click="vm.cancelCreate()" class="cancel-create">Abbruch</span>
</div>
<div class="bar bar-subheader">
<form class="create-form" role="form"
ng-submit="vm.create(vm.newObject)" novalidate>
<div class="list">
<label class="item item-input item-stacked-label">
<span class="input-label">Name</span>
<input type="text" class="form-control"
ng-model="vm.newObject.name"
placeholder="Gib einen Namen ein">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Beschreibung</span>
<textarea placeholder="Beschreibung" class="form-control"
ng-model="vm.newObject.description"></textarea>
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Preis</span>
<textarea placeholder="Preis" class="form-control"
ng-model="vm.newObject.price"
typeof="float"></textarea>
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Bild</span>
<input type="text" class="form-control"
ng-model="vm.newObject.imgurl"
placeholder="Gib einen Bildlink ein">
</label>
</div>
<button class="button button-block button-balanced" type="submit">Fertig</button>
</form>
</div>
</ion-content>
</div>
<div ng-if="vm.isEditing && !vm.isCreating">
<ion-content class="padding has-header">
<!-- Bearbeiten -->
<div class="bar bar-header bar-secondary">
<h1 class="title">Bearbeiten</h1>
<span ng-click="vm.cancelEditing()" class="cancel-create">Abbrechen</span>
</div>
<div class="bar bar-subheader">
<form class="edit-form" role="form"
ng-submit="vm.update(vm.edited)" novalidate>
<div class="list">
<label class="item item-input item-stacked-label">
<span class="input-label">Name</span>
<input type="text" class="form-control"
ng-model="vm.edited.name"
placeholder="Gib einen Namen ein">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Beschreibung</span>
<textarea class="form-control"
ng-model="vm.edited.description"
placeholder="Beschreibung"></textarea>
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Preis</span>
<textarea placeholder="Preis" class="form-control"
ng-model="vm.edited.price"
type="float"></textarea>
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Bild</span>
<textarea class="form-control"
ng-model="vm.edited.imgurl"
placeholder="Bildlink"></textarea>
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Auswählen</span>
<textarea class="form-control"
ng-model="vm.edited.check"
placeholder="true" type="boolean"></textarea>
</label>
</div>
<button class="button button-block button-balanced" type="submit">Speichern</button>
</form>
</div>
</ion-content>
</div>

thanks for using Backand! There is a default page size filter that you can modify in your getList() call. It is available in our new SDK - if you update to the latest version of the starter project you downloaded, it should already have the appropriate changes built-in. For reference, our new SDK can be found at https://github.com/backand/vanilla-sdk
Regarding resolving your issue, in order to adjust the page size, you can pass in an additional parameter to the getList function that dynamically changes the number of records you can retrieve. Here's some sample code that matches your use case:
service.all = function () {
params = { pageSize: 100 }; // Changes page size to 100
return Backand.object.getList('items', params);
};
Using the old SDK, you can do something similar by appending the parameters query param to the URL you use to drive your GET request.

Related

Form reset issue after get response via API in react js

I am submitting form via redux API call and getting response but on success response I am trying to reset form but that giving issue -
setState(...): Cannot update during an existing state transition (such as withinrenderor another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to 'componentWillMount'.
here is my from file -
=========================
import React from 'react';
import DefaultLayout from '../Layout/DefaultLayout';
//import $ from 'jquery';
import { connect } from 'react-redux';
import { contactRequest } from '../actions/signupActions';
import { bindActionCreators } from 'redux';
import validator from 'validator';
class Contactus extends React.Component {
constructor(props){
super(props);
document.title = "Contact Us";
this.errorMapping = {"100": "Your message has been submitted.",
"102": "Name cannot be empty.",
"104": "Email cannot be empty.",
"103": "Hotel cannot be empty.",
"105": "Incorrect email format.",
"106": "Phone cannot be empty."}
this.state = {name: '',email:'',message :''};
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.baseState = this.state
}
handleInputChange(event) {
this.setState({ [event.target.name]: event.target.value});
}
handleSubmit(event) {
event.preventDefault();
this.props.contactRequest(this.state);
}
render(){
const style_1 = {height: '240px'};
const style_2 = {marginRight: '15px'};
const style_3 = {width: 'auto'};
return(
<DefaultLayout>
<section id="content">
<div className="content-wrap">
<div className="container clearfix">
<div className="col-md-6 bottommargin">
<section id="google-map" className="gmap" style={style_1} ></section>
</div>
<div className="col-md-6">
Click here to Send an Email
Send an Email
<div className="modal fade" id="contactFormModal" tabIndex="-1" role="dialog" aria-labelledby="contactFormModalLabel" aria-hidden="true">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-body">
<div className="contact-widget">
<div className="contact-form-result">
{this.props.resultMessage && this.props.resultMessage.status.map((msg, idx) => {
if(msg === 100) {
this.setState({name : "",email : ""});
return <span key={idx} id="succ_msg">{this.errorMapping[msg]}</span>
} else {
return <span key={idx} id="err_msg">{this.errorMapping[msg]}</span>
}
})
}
</div>
<form className="nobottommargin" id="r_contactform" name="r_contactform" method="post" onSubmit={this.handleSubmit} ref={(el) => this.myFormRef = el} >
<div className="form-process"></div>
<div className="col_half">
<label htmlFor="template-contactform-name">Name <small>*</small></label>
<input type="text" id="template-contactform-name" name="name" value={this.state.name} className="sm-form-control required" onChange={this.handleInputChange} />
</div>
<div className="col_half col_last">
<label htmlFor="template-contactform-email">Email <small>*</small></label>
<input type="email" id="template-contactform-email" name="email" value={this.state.email} className="required email sm-form-control" onChange={this.handleInputChange} />
</div>
<div className="clear"></div>
<div className="clear"></div>
<div className="col_half">
<label htmlFor="template-contactform-message">Message <small>*</small></label>
<textarea className="required sm-form-control" id="template-contactform-message" name="message" value={this.state.message} rows="6" cols="30" onChange={this.handleInputChange}></textarea>
<span className={this.state.messageError ? 'help-block error': '' }>{ this.state.messageError ? this.state.messageError: '' }</span>
</div>
<div className="col_full">
<button className="button button-3d nomargin" type="submit" id="contactform-submit" name="contactform-submit">Send Message</button>
</div>
</form>
</div>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</DefaultLayout>
);
}
}
function mapStateToProps(state){
console.log("View data :"+JSON.stringify(state.Contactdata));
return {
resultMessage: state.Contactdata
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({contactRequest: contactRequest}, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps) (Contactus);
getting response in mapStateToProps function and trying to update state where I have applied condition if(msg === 100) .
Please let me know where I am doing wrong.
thanks
The right place to setState is not in the map function, since you are receiving props from redux, you can do it in the componentWillReceiveProps fucntion
class Contactus extends React.Component {
constructor(props){
super(props);
document.title = "Contact Us";
this.errorMapping = {"100": "Your message has been submitted.",
"102": "Name cannot be empty.",
"104": "Email cannot be empty.",
"103": "Hotel cannot be empty.",
"105": "Incorrect email format.",
"106": "Phone cannot be empty."}
this.state = {name: '',email:'',message :''};
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.baseState = this.state
}
componentWillReceiveProps(nextProps) {
nextProps.resultMessage.status.forEach((msg, idx) => {
if(msg === 100) {
this.setState({name : "",email : ""});
}
}
}
handleInputChange(event) {
this.setState({ [event.target.name]: event.target.value});
}
handleSubmit(event) {
event.preventDefault();
this.props.contactRequest(this.state);
}
render(){
const style_1 = {height: '240px'};
const style_2 = {marginRight: '15px'};
const style_3 = {width: 'auto'};
return(
<DefaultLayout>
<section id="content">
<div className="content-wrap">
<div className="container clearfix">
<div className="col-md-6 bottommargin">
<section id="google-map" className="gmap" style={style_1} ></section>
</div>
<div className="col-md-6">
Click here to Send an Email
Send an Email
<div className="modal fade" id="contactFormModal" tabIndex="-1" role="dialog" aria-labelledby="contactFormModalLabel" aria-hidden="true">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-body">
<div className="contact-widget">
<div className="contact-form-result">
{this.props.resultMessage && this.props.resultMessage.status.map((msg, idx) => {
if(msg === 100) {
return <span key={idx} id="succ_msg">{this.errorMapping[msg]}</span>
} else {
return <span key={idx} id="err_msg">{this.errorMapping[msg]}</span>
}
})
}
</div>
<form className="nobottommargin" id="r_contactform" name="r_contactform" method="post" onSubmit={this.handleSubmit} ref={(el) => this.myFormRef = el} >
<div className="form-process"></div>
<div className="col_half">
<label htmlFor="template-contactform-name">Name <small>*</small></label>
<input type="text" id="template-contactform-name" name="name" value={this.state.name} className="sm-form-control required" onChange={this.handleInputChange} />
</div>
<div className="col_half col_last">
<label htmlFor="template-contactform-email">Email <small>*</small></label>
<input type="email" id="template-contactform-email" name="email" value={this.state.email} className="required email sm-form-control" onChange={this.handleInputChange} />
</div>
<div className="clear"></div>
<div className="clear"></div>
<div className="col_half">
<label htmlFor="template-contactform-message">Message <small>*</small></label>
<textarea className="required sm-form-control" id="template-contactform-message" name="message" value={this.state.message} rows="6" cols="30" onChange={this.handleInputChange}></textarea>
<span className={this.state.messageError ? 'help-block error': '' }>{ this.state.messageError ? this.state.messageError: '' }</span>
</div>
<div className="col_full">
<button className="button button-3d nomargin" type="submit" id="contactform-submit" name="contactform-submit">Send Message</button>
</div>
</form>
</div>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</DefaultLayout>
);
}
}
This is the reason, you are doing setState inside render method:
{this.props.resultMessage && this.props.resultMessage.status.map((msg, idx) => {
if(msg === 100) {
this.setState({name : "",email : ""});
.....
When msg==100 will be true, you are doing setState, again it will trigger re-rendering, again setState ....... infinite loop.
Remove that setState it will work.
Use componentWillReceiveProps lifecycle method, and do the setState inside that.
componentWillReceiveProps(newProps) {
newProps.resultMessage.status.forEach((msg, idx) => {
if(msg === 100) {
this.setState({
name : "",
email : ""
});
}
}
}

angular4 form saving exception

hi every body i am using angular 4 , when i save form in deployment mode, i get the error down , and when i save the same form in development mode i don't get the exception.
my form code products-form.component.ts :
import {Component, OnInit, OnDestroy, ViewChild, ElementRef} from '#angular/core';
import {NgForm} from '#angular/forms';
import {AdminService} from "../../../services/admin.service";
import {HttpService} from "../../../../http.service";
import {Subscription} from "rxjs";
import {Http, Response, Headers,RequestOptions} from "#angular/http";
import {ActivatedRoute, Router} from "#angular/router";
import { trigger, state, style, transition, animate } from '#angular/animations';
import {BrowserAnimationsModule} from '#angular/platform-browser/animations';
import {BusyModule} from 'angular2-busy';
import { FormGroup, FormBuilder, Validators,ReactiveFormsModule } from '#angular/forms';
import { BrowserModule } from '#angular/platform-browser';
import {MdDialog, MdDialogRef} from '#angular/material';
import {DiscardPopUpComponent} from '../../../../discard-pop-up/discard-pop-up.component';
#Component({
selector: 'app-products-form',
templateUrl: './products-form.component.html',
styleUrls: ['./products-form.component.css']
})
export class ProductsFormComponent implements OnInit, OnDestroy {
product:any = {'needTransformer':'Yes',
'power':'',
'cct':'',
'cri':'',
'lightSource':'',
'country':'',
'category':{},
'productionCompany':{},
'finish':{}};
discardPopUpTitle:string = "Discard Changes";
discardPopUpContent:string="Are you Sure you want to discard changes and exit to products table ?";
selectedPopUpOption:string;
discardDialog:DiscardPopUpComponent;
showPopUp = false;
popUpresult = false;
isFormDirty:boolean=false;
companies: string[] =[];
companiesSubscription: Subscription;
finishes: string[] = [];
finishesSubscription: Subscription;
categories: string[] = [];
categoriesSubscription: Subscription;
lightSources: string[] = [];
lightSourcesSubscription: Subscription;
countries: string[] = [];
countriesSubscription: Subscription;
routeSubscritpion: Subscription;
selectedCategory: string;
selectedFinish: string;
selectedProductionCompany: string;
selectedLightSource: string;
selectedCountry: string;
selectedTransformerNeeded: string;
isEdit: boolean = false;
isShow: boolean = false;
message: string;
#ViewChild('mainImage') mainImage: ElementRef;
#ViewChild('diemsnions') diemsnions: ElementRef;
#ViewChild('effects') effects: ElementRef;
#ViewChild('pdf') pdf: ElementRef;
#ViewChild('categoryEl') categoryEl: ElementRef;
busy: any;
isSuccess: boolean = false;
currentCode: string;
constructor(private httpService:HttpService, private adminService: AdminService, private http: Http, private route: ActivatedRoute, private router: Router,public dialog: MdDialog) {
console.log(dialog);
this.discardDialog = new DiscardPopUpComponent();
}
ngOnInit() {
// this.busy = true;
this.routeSubscritpion = this.route.params.subscribe(param => {
let code = param['code'];
if(code != undefined)
this.httpService.getProductDataByCode(code).subscribe(
(data:any)=> {
this.product=data;
this.currentCode = data.code;
this.isEdit = true;
this.selectedCategory = data.category.name;
this.selectedFinish = data.finish.name;
this.selectedCountry = data.country;
this.selectedProductionCompany = data.productionCompany.name;
this.selectedLightSource = data.lightSource;
this.selectedTransformerNeeded = data.transformerNeeded;
// this.categoryEl.nativeElement.value = data.category.name;
},
(err) => console.error(err+"<-------------"),
() => console.log('Random Quote Complete')
);
});
this.companiesSubscription = this.httpService.getAllCompanies().subscribe(
(data:any)=> {
data.forEach((entry)=> {
this.companies.push(entry.name);
});
if(this.companies.length > 0)
this.product.productionCompany = this.companies[0];
},
(err) => console.error(err+"<-------------"),
() => console.log('Random Quote Complete')
);
this.categoriesSubscription = this.httpService.getAllCategories().subscribe(
(data:any)=> {
data.forEach((entry)=> {
this.categories.push(entry.name);
});
if(this.categories.length > 0)
this.product.category = this.categories[0];
},
(err) => console.error(err+"<-------------"),
() => console.log('Random Quote Complete')
);
this.finishesSubscription = this.httpService.getAllFinishes().subscribe(
(data:any)=> {
data.forEach((entry)=> {
this.finishes.push(entry.name);
});
if(this.finishes.length > 0)
this.product.finish = this.finishes[0];
},
(err) => console.error(err+"<-------------"),
() => console.log('Random Quote Complete')
);
this.lightSourcesSubscription = this.httpService.getAllLightSources().subscribe(
(data:any)=> {
this.lightSources = data;
if(this.lightSources.length > 0)
this.product.lightSource = this.lightSources[0];
},
(err) => console.error(err+"<-------------"),
() => console.log('Random Quote Complete')
);
this.httpService.getAllCountries().subscribe(
(data:any)=> {
this.countries = data;
if(this.countries.length > 0)
this.product.country = this.countries[0];
},
(err) => console.error(err+"<-------------"),
() => console.log('Random Quote Complete')
);
}
readUrl(event,url) {
if (event.target.files && event.target.files[0]) {
var reader = new FileReader();
reader.onload = (event) => {
var target:FileReader=<FileReader>event.target;
this.product[url] = target.result;
}
reader.readAsDataURL(event.target.files[0]);
}
}
formatStrings(str)
{
str=str.replace(/\s/g, '');
str=str.replace(/,/g, '');
str=str.toUpperCase();
return str
}
onSubmit(form:NgForm)
{
var values=form.value;
let parent=this;
let obj={
name:values.name,
description:values.description,
code:values.code,
category:{
name:values.categories
},
productionCompany:{
name:values.productionCompany
},
finish:{
name:values.finish
},
transformerNeeded:values.transformerNeeded,
power:values.power,
cct:values.cct,
cri:values.cri,
ik: values.ik,
ip: values.ip,
luminous: values.luminous,
optic: values.optic,
lightSource:values.lightSource,
country:values.productionContry,
effictImagePath:'',
normalImagePath:'',
detailsImagePath:'',
catalogPath:''
};
let headers = new Headers({ 'Content-Type': 'application/json' ,'Authorization': JSON.parse(localStorage.getItem('currentUser'))['token']});
let options = new RequestOptions({ headers: headers });
if(!this.isEdit) {
this.busy = this.http.post('http://levelskw.com/products/', JSON.stringify(obj), options).subscribe(
(data: any) => {
this.product=obj;
this.currentCode = obj.code;
this.isEdit = true;
this.selectedCategory = obj.category.name;
this.selectedFinish = obj.finish.name;
this.selectedCountry = obj.country;
this.selectedProductionCompany = obj.productionCompany.name;
this.selectedLightSource = obj.lightSource;
this.selectedTransformerNeeded = obj.transformerNeeded;
this.isSuccess = true;
this.message="Success";
parent.upload(obj.code)
},
(err) => {
this.isSuccess = false;
this.message=JSON.parse(err._body).msg;
this.isShow = true;
let timeoutId = setTimeout(() => {
this.isShow = false;
}, 5000);
},
() => console.log("")
);
} else {
this.busy = this.http.put('http://levelskw.com/products/'+this.currentCode, JSON.stringify(obj), options).subscribe(
(data: any) => {
this.isSuccess = true;
this.message="Success";
parent.upload(this.currentCode);
},
(err) =>{
this.isSuccess = false;
this.message=JSON.parse(err._body).msg;
this.isShow = true;
let timeoutId = setTimeout(() => {
this.isShow = false;
}, 5000);
},
() => console.log("")
);
}
console.log(JSON.stringify(obj));
}
ngOnDestroy() {
this.isFormDirty = false;
this.companiesSubscription.unsubscribe();
this.finishesSubscription.unsubscribe();
this.lightSourcesSubscription.unsubscribe();
}
changeFinish(finish) {
this.product.finish = finish;
console.log(this.product);
}
makeFileRequest(url:string) {
return new Promise((resolve, reject) => {
let mainImageEl: HTMLInputElement = this.mainImage.nativeElement;
let formData = new FormData();
let xhr = new XMLHttpRequest();
if (mainImageEl.files.length > 0)
formData.append("normalImagePath", mainImageEl.files.item(0), mainImageEl.files.item(0).name);
let diemsnionsEl: HTMLInputElement = this.diemsnions.nativeElement;
if (diemsnionsEl.files.length > 0)
formData.append("detailsImagePath", diemsnionsEl.files.item(0), diemsnionsEl.files.item(0).name);
let effectsEl: HTMLInputElement = this.effects.nativeElement;
if (effectsEl.files.length > 0)
formData.append("effictImagePath", effectsEl.files.item(0), effectsEl.files.item(0).name);
let pdfEl: HTMLInputElement = this.pdf.nativeElement;
if (pdfEl.files.length > 0)
formData.append("catalogPath", pdfEl.files.item(0), pdfEl.files.item(0).name);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
resolve(JSON.parse(xhr.response));
} else {
reject(xhr.response);
}
}
};
xhr.open("POST", url, true);
xhr.setRequestHeader("Authorization", JSON.parse(localStorage.getItem('currentUser'))['token']);
xhr.send(formData);
});
}
upload(code: string) {
this.busy = this.makeFileRequest("http://levelskw.com/products/upload/"+code).then((result) => {
this.isShow = true;
let timeoutId = setTimeout(() => {
this.isShow = false;
}, 5000);
}, (error) => {
this.isShow = true;
let timeoutId = setTimeout(() => {
this.isShow = false;
}, 5000);
});
}
cancel() {
this.router.navigate(['/admin/products']);
}
openDialog() {
this.showPopUp=true;
this.discardDialog.show();
}
takePopUpEvent(isPopUpValueConfermed:boolean){
this.popUpresult = isPopUpValueConfermed;
if(this.popUpresult){
this.cancel() ;
}else{
this.showPopUp=false;
}
}
onChange(form:NgForm){
console.log(form);
this.isFormDirty = true;
}
}
my HTML code products-form.component.html :
<app-popup [isShow]="isShow" [message]="message" [isSuccess]="isSuccess"></app-popup>
<div [ngBusy]="busy"></div>
<div class="main-container">
<form (ngSubmit)="onSubmit(f)" #f="ngForm">
<app-discard-pop-up [showPopUp]="showPopUp" [popUpTitle]="discardPopUpTitle" [popUpContent]="discardPopUpContent" (isConfermed)="takePopUpEvent($event)" ></app-discard-pop-up>
<div fxLayout="column" fxLayoutGap="15px">
<div fxLayout="row" fxLayoutGap="29px">
<div fxLayout="column" fxLayoutGap="20px">
<div fxLayout="column" class='titleSection'>
<div class="header"><div class='header-label'>Header</div></div>
<div class='title'><input type="text" placeholder="Code" name="code" [(ngModel)]="product.code" (ngModelChange)="onChange(f)" /></div>
<div class='title'><input type="text" placeholder="Name" name="name" [(ngModel)]="product.name" (ngModelChange)="onChange(f)" /></div>
<div class="description"><textarea placeholder="Description" name="description" [(ngModel)]="product.description" (ngModelChange)="onChange(f)" ></textarea></div>
</div>
<div fxLayout="column" class="loadSection">
<div class="header"><div class='header-label'>Files</div></div>
<div fxLayout="column" class="img-section" fxLayoutGap="2px">
<div class="img-lable">Main image</div>
<div class="img-btn">
<button fxLayoutAlign="center center">Upload</button>
<img class="img-view" [src]="product.normalImagePath" />
<input type="file" (change)="readUrl($event,'normalImagePath')" #mainImage (ngModelChange)="onChange(f)" />
</div>
</div>
<div fxLayout="column" class="img-section" fxLayoutGap="2px">
<div class="img-lable">Dimensions</div>
<div class="img-btn">
<button fxLayoutAlign="center center">Upload</button>
<img class="img-view" [src]="product.detailsImagePath" />
<input type="file" (change)="readUrl($event,'detailsImagePath')" #diemsnions (ngModelChange)="onChange(f)" />
</div>
</div>
<div fxLayout="column" class="img-section" fxLayoutGap="2px">
<div class="img-lable">Effects</div>
<div class="img-btn">
<button fxLayoutAlign="center center">Upload</button>
<img class="img-view" [src]="product.effictImagePath" />
<input type="file" (change)="readUrl($event,'effictImagePath')" #effects (ngModelChange)="onChange(f)" />
</div>
</div>
<div fxLayout="column" class="img-section" fxLayoutGap="2px">
<div class="img-lable">PDF</div>
<div class="img-btn">
<button fxLayoutAlign="center center">Upload</button>
<img class="img-view" src="../../../../assets/Icons/pdf.png" />
<input type="file" #pdf (ngModelChange)="onChange(f)" />
</div>
</div>
</div>
</div>
<div fxLayout="column" class="details" fxLayoutGap="10px">
<div class="header"><div class='header-label'>Related Products</div></div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Category</div>
<select class="dropdown" name="categories" [(ngModel)]="selectedCategory" (ngModelChange)="onChange(f)" >
<option *ngFor="let category of categories" [ngValue]="category">{{category}}</option>
</select>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Manufactured By</div>
<select class="dropdown" name="productionCompany" [(ngModel)]="selectedProductionCompany" (ngModelChange)="onChange(f)" >
<option *ngFor="let company of companies" [ngValue]="company">{{company}}</option>
</select>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Materials</div>
<select class="dropdown" name="finish" [(ngModel)]="selectedFinish" (ngModelChange)="onChange(f)" >
<option *ngFor="let finish of finishes" [ngValue]="finish">{{finish}}</option>
</select>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Transformer needed</div>
<select class="dropdown" name="transformerNeeded" [(ngModel)]="selectedTransformerNeeded" (ngModelChange)="onChange(f)" >
<option value="true" selected>Yes</option>
<option value="false" >No</option>
</select>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Power(W)</div>
<input type="number" name="power" [(ngModel)]="product.power" (ngModelChange)="onChange(f)"/>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>CCT(K)</div>
<div fxLayout="row">
<input type="number" name="cct" [(ngModel)]="product.cct" #cct="ngModel" number (ngModelChange)="onChange(f)" />
<div class="validation-error-message"> <p *ngIf="cct.errors?.number" color:red> CCT should be number</p></div>
</div>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>IK</div>
<input type="number" name="ik" [(ngModel)]="product.ik" (ngModelChange)="onChange(f)" />
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Index of protection</div>
<input type="number" name="ip" [(ngModel)]="product.ip" (ngModelChange)="onChange(f)" />
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Luminous</div>
<input type="number" name="luminous" [(ngModel)]="product.luminous" (ngModelChange)="onChange(f)" />
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Optic</div>
<input type="number" name="optic" [(ngModel)]="product.optic" (ngModelChange)="onChange(f)" />
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>CRI</div>
<input type="number" name="cri" [(ngModel)]="product.cri" (ngModelChange)="onChange(f)" />
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Light Source</div>
<select class="dropdown" name="lightSource" [(ngModel)]="selectedLightSource" (ngModelChange)="onChange(f)" >
<option *ngFor="let lightSource of lightSources" [ngValue]="formatStrings(lightSource)" >{{lightSource}}</option>
</select>
</div>
</div>
<div fxLayout="column">
<div class="item-cont">
<div class='lable'>Production country</div>
<select class="dropdown" name="productionContry" [(ngModel)]="selectedCountry" (ngModelChange)="onChange(f)" >
<option *ngFor="let company of countries" [ngValue]="formatStrings(company)" >{{company}}</option>
</select>
</div>
</div>
</div>
</div>
<div class='control-btn-container'>
<div fxLayout="row" fxLayoutGap="10px">
<button class="btn cancel" fxLayoutAlign="center center" (click)="cancel()">Cancel</button>
<button type="submit" class="btn save" fxLayoutAlign="center center" >Save</button>
</div>
</div>
</div>
</form>
</div>
i use spring boot in the backend.
ERROR Error: Uncaught (in promise): Error: Runtime compiler is not loaded
Error: Runtime compiler is not loaded
at y (vendor.600ff6e….bundle.js:781)
at Z (vendor.600ff6e….bundle.js:218)
at t.compileModuleAndAllComponentsAsync (vendor.600ff6e….bundle.js:365)
at vendor.600ff6e….bundle.js:521
at t.invoke (vendor.600ff6e….bundle.js:781)
at Object.onInvoke (vendor.600ff6e….bundle.js:365)
at t.invoke (vendor.600ff6e….bundle.js:781)
at e.run (vendor.600ff6e….bundle.js:781)
at vendor.600ff6e….bundle.js:781
at t.invokeTask (vendor.600ff6e….bundle.js:781)
at Object.onInvokeTask (vendor.600ff6e….bundle.js:365)
at t.invokeTask (vendor.600ff6e….bundle.js:781)
at e.runTask (vendor.600ff6e….bundle.js:781)
at s (vendor.600ff6e….bundle.js:781)
at HTMLFormElement.invoke (vendor.600ff6e….bundle.js:781)
at y (vendor.600ff6e….bundle.js:781)
at Z (vendor.600ff6e….bundle.js:218)
at t.compileModuleAndAllComponentsAsync (vendor.600ff6e….bundle.js:365)
at vendor.600ff6e….bundle.js:521
at t.invoke (vendor.600ff6e….bundle.js:781)
at Object.onInvoke (vendor.600ff6e….bundle.js:365)
at t.invoke (vendor.600ff6e….bundle.js:781)
at e.run (vendor.600ff6e….bundle.js:781)
at vendor.600ff6e….bundle.js:781
at t.invokeTask (vendor.600ff6e….bundle.js:781)
at Object.onInvokeTask (vendor.600ff6e….bundle.js:365)
at t.invokeTask (vendor.600ff6e….bundle.js:781)
at e.runTask (vendor.600ff6e….bundle.js:781)
at s (vendor.600ff6e….bundle.js:781)
at HTMLFormElement.invoke (vendor.600ff6e….bundle.js:781)
at y (vendor.600ff6e….bundle.js:781)
at p (vendor.600ff6e….bundle.js:781)
at vendor.600ff6e….bundle.js:781
at t.invokeTask (vendor.600ff6e….bundle.js:781)
at Object.onInvokeTask (vendor.600ff6e….bundle.js:365)
at t.invokeTask (vendor.600ff6e….bundle.js:781)
at e.runTask (vendor.600ff6e….bundle.js:781)
at s (vendor.600ff6e….bundle.js:781)
at HTMLFormElement.invoke (vendor.600ff6e….bundle.js:781)

Cannot find a differ supporting object '[object Object]' of type, Angular 2

I'm newbie in Angular 2 and trying to write a simple ng-form following by official tutorial.
If I'm using simple array from tutorial, it works fine:
powers = ['Really Smart', 'Super Flexible',
'Super Hot', 'Weather Changer'];
But when I'm changing it on my custom array from http
public departments = [];
constructor(http: Http) {
http.get('/api/departments')
.map((res: Response) => res.json())
.subscribe((departments: Array<Object>) => this.departments = departments);
}
I'm getting an error:
error_handler.js:51 Error: Uncaught (in promise): Error: Error in ./AddClientComponent class AddClientComponent - inline template:41:12 caused by: Cannot find a differ supporting object '[object Object]' of type 'departments'. NgFor only supports binding to Iterables such as Arrays.
So where is my mistake and what am I missing? thanks in advance.
AddClientComponent
import 'rxjs/add/operator/map';
import {Component} from '#angular/core';
import {Http, Response} from '#angular/http';
import { DepartmentsComponent } from '../departments/departments.component';
#Component({
selector: 'app-add-client',
templateUrl: './add-client.component.html',
styleUrls: ['./add-client.component.css']
})
export class AddClientComponent {
public departments = [];
public firstName = '';
public lastName = '';
public id = null;
constructor(http: Http) {
http.get('/api/departments')
.map((res: Response) => res.json())
.subscribe((departments: Array<Object>) => this.departments = departments);
}
model = new Employee(
this.id,
this.firstName,
this.lastName,
this.departments
);
submitted = false;
onSubmit() { this.submitted = true; }
active = true;
}
export class Employee {
constructor(
public id: number,
public firstName: string,
public lastName: string,
public departments: any
) { }
}
html
<div class="container">
<div [hidden]="submitted">
<h1>Employee Form</h1>
<form *ngIf="active" (ngSubmit)="onSubmit()" #employeeForm="ngForm">
<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" class="form-control" id="firstName"
required
[(ngModel)]="model.firstName"
name="firstName"
#firstName="ngModel" >
<div [hidden]="firstName.valid || firstName.pristine"
class="alert alert-danger">
First Name is required
</div>
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" class="form-control" id="lastName"
required
[(ngModel)]="model.lastName"
name="lastName"
#lastName="ngModel" >
<div [hidden]="lastName.valid || lastName.pristine"
class="alert alert-danger">
Last Name is required
</div>
</div>
<div class="form-group">
<label for="departments">Department</label>
<select class="form-control" id="departments"
required
[(ngModel)]="model.departments"
name="departments"
#departments="ngModel" >
<option
*ngFor="let department of departments"
[value]="department">{{department.name}}
</option>
</select>
<div [hidden]="departments.valid || departments.pristine"
class="alert alert-danger">
Department is required
</div>
</div>
<button type="submit"
class="btn btn-default"
[disabled]="!employeeForm.form.valid">Submit
</button>
<!--<button type="button"-->
<!--class="btn btn-default"-->
<!--(click)="newHero()">New Hero-->
<!--</button>-->
</form>
</div>
<div [hidden]="!submitted">
<h2>You submitted the following:</h2>
<div class="row">
<div class="col-xs-3">First Name</div>
<div class="col-xs-9 pull-left">{{ model.firstName }}</div>
</div>
<div class="row">
<div class="col-xs-3">Last Name</div>
<div class="col-xs-9 pull-left">{{ model.lastName }}</div>
</div>
<div class="row">
<div class="col-xs-3">Department</div>
<div class="col-xs-9 pull-left">{{ model.departments }}</div>
</div>
<br>
<button class="btn btn-default" (click)="submitted=false">Edit</button>
</div>
</div>
Use a different name for
#departments="ngModel"
I think it overloads the departments property of the class used in *ngFor
Try changing type
public departments: Array<any> = [];
constructor(http: Http) {
http.get('/api/departments')
.map((res: Response) => res.json())
.subscribe((departments: Array<any>) => this.departments = departments);
}

ionic, select input (type number) content on click / focus

In my Ionic app, as you can see, this "select-on-focus" directive doesn't work in iOS...
Here's a video:
https://youtu.be/_bOWGMGesgk
Here's the code:
<div class="wrapperFlex withNextButton">
<div class="itemTitle">
<div class="text">
{{'paramQuestions.weight' | translate }}
</div>
</div>
<div id="weightdata" class="itemParameters weightdataclass row">
<input class="weightinput" type="number" name="userweight" ng-min="{{data.minWeight}}" ng-max="{{data.maxWeight}}" ng-model="data.realWeight" ng-change="updateViewGenVol(data.weightunit, data.userweight, data.BLfactorValue);saveUserWeight()" select-on-focus required></input>
<div class="weightunitradios">
<ion-checkbox class="checkboxes checkbox-blueboardline" ng-model="data.weightunit" ng-true-value="'kg'" ng-false-value="'lbs'" ng-change="saveWeightUnit(); changeMinMax(); convertWeightInput(); saveUserWeight();">kg</ion-checkbox>
<ion-checkbox class="checkboxes checkbox-blueboardline" ng-model="data.weightunit" ng-true-value="'lbs'" ng-false-value="'kg'" ng-change="saveWeightUnit(); changeMinMax(); convertWeightInput(); saveUserWeight();">lbs</ion-checkbox>
</div>
</div>
</div>
directives.js:
.directive('selectOnFocus', function ($timeout) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var focusedElement = null;
element.on('focus', function () {
var self = this;
if (focusedElement != self) {
focusedElement = self;
$timeout(function () {
self.select();
}, 10);
}
});
element.on('blur', function () {
focusedElement = null;
});
}
}
})

how do you enable/disable submit button based on form contents in Material Design Lite?

I have a submit button for a login form which is disabled by default. I want to enable it when the user enters a valid username/password. There are quite a few examples using AngularJS, JQuery, and other infrastructures but i would like to know a clean way to do it with Material Design Lite. My current code is:
class FrontPage extends Component {
constructor(props, context) {
super(props, context);
this.state = { email: '', password: '' };
}
handleEmailChange() {
this.setState({email: e.target.value})
}
handlePasswordChange() {
this.setState({password: e.target.value})
}
render() {
return(
<form className="frontpage" onSubmit={this.handleLogin}>
<div className="content-grid mdl-grid">
<div className="mdl-cell mdl-textfield mdl-js-textfield">
<input className="mdl-textfield__input" id="email" type="email" value={this.state.email} onChange={this.handleEmailChange}/>
<label className="mdl-textfield__label" htmlFor="email">email...</label>
<span className="mdl-textfield__error">Input is not an email address!</span>
</div>
<div className="mdl-cell mdl-textfield mdl-js-textfield">
<input className="mdl-textfield__input" id="password" type="password" pattern="[A-Z,a-z,0-9\?#\$%&\*\-_=+! ~\.,\/\\]*" value={this.state.password} onChange={this.handlePasswordChange}/>
<label className="mdl-textfield__label" htmlFor="password">password...</label>
<span className="mdl-textfield__error">Input can only contain letters, numbers, and some special characters!</span>
</div>
<div classname="mdl-cell">
<button className="mdl-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" type="submit" name="login" disabled>Login</button>
</div>
</div>
</form>
)
}
}
<button id='loginBtn' className="mdl-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" type="submit" name="login" disabled>Login</button>
<script>
function Enable() {
var loginBtn = document.getElementById('loginBtn');
loginBtn.removeAttribute("disabled");
componentHandler.upgradeElement(loginBtn);
}
function Disable() {
var loginBtn = document.getElementById('loginBtn');
loginBtn.setAttribute("disabled","");
componentHandler.upgradeElement(loginBtn);
}
</script>