The changed value is not reflecting on the input field in ReactJS, TestUtils - unit-testing

I am using ReactJs and Mocha and trying few unit tests. I have two mandatory form fields First Name and Last Name. I am trying to test the validation where if only one field is entered, the other field displays the missing value validation error.
Below code simulates the changes to the value and simulates the form submit.
TestUtils.Simulate.change(firstNameElement , {target: {value: 'Joe'}});
TestUtils.Simulate.submit(formElement)
The changed value is reflected in the event handlers on First Name. But, not in the test. So, both the fields display missing value validation failing my test.
What I could be doing wrong here?
Below are code:
//NameForm.jsx
'use strict';
var React=require('react')
var forms = require('newforms')
var NameForm = forms.Form.extend({
firstName: forms.CharField({maxLength: 100, label: "First name(s)"}),
lastName: forms.CharField({maxLength: 100, label: "Last name"}),
cleanFirstName(callback) {
callback(null)
},
render() {
return this.boundFields().map(bf => {
return <div className={'form-group ' + bf.status()}>
<label className="form-label" htmlFor={bf.name}>
<span className="form-label-bold">{bf.label}</span>
</label>
{bf.errors().messages().map(message => <span className="error-message">{message}</span>)}
<input className="form-control" id={bf.name} type="text" name={bf.name} onChange = {this.onChangeHandler}/>
</div>
})
}
, onChangeHandler: function(e){
console.log("onchnage on input is called ----- >> " + e.target.value)
}
})
module.exports = {
NameForm
}
Here is NamePage.jsx:
'use strict';
var React = require('react')
var {ErrorObject} = require('newforms')
var superagent = require('superagent-ls')
var {API_URL} = require('../../constants')
var {NameForm} = require('./NameForm')
var NamePage = React.createClass({
contextTypes: {
router: React.PropTypes.func.isRequired
},
propTypes: {
data: React.PropTypes.object,
errors: React.PropTypes.object
},
statics: {
title: 'Name',
willTransitionTo(transition, params, query, cb, req) {
if (req.method != 'POST') { return cb() }
superagent.post(`${API_URL}/form/NameForm`).send(req.body).withCredentials().end((err, res) => {
if (err || res.serverError) {
return cb(err || new Error(`Server error: ${res.body}`))
}
if (res.clientError) {
transition.redirect('name', {}, {}, {
data: req.body,
errors: res.body
})
}
else {
transition.redirect('summary')
}
cb()
})
}
},
getInitialState() {
return {
client: false,
form: new NameForm({
onChange: this.forceUpdate.bind(this),
data: this.props.data,
errors: this._getErrorObject()
})
}
},
componentDidMount() {
this.setState({client: true})
},
componentWillReceiveProps(nextProps) {
if (nextProps.errors) {
var errorObject = this._getErrorObject(nextProps.errors)
this.refs.nameForm.getForm().setErrors(errorObject)
}
},
_getErrorObject(errors) {
if (!errors) { errors = this.props.errors }
return errors ? ErrorObject.fromJSON(errors) : null
},
_onSubmit(e) {
e.preventDefault()
var form = this.state.form
form.validate(this.refs.form, (err, isValid) => {
if (isValid) {
this.context.router.transitionTo('name', {}, {}, {
method: 'POST',
body: form.data
})
}
})
},
render() {
return <div>
<h1 className="heading-large">Your name</h1>
<form action='name' method="POST" onSubmit={this._onSubmit} ref="form" autoComplete="off" noValidate={this.state.client}>
{this.state.form.render()}
<button type="submit" className="button">Next</button>
</form>
</div>
},
})
module.exports = NamePage
Here is NameTest.js :
//NameTest.js
var React = require('react')
var ReactAddons = require('react/addons')
var TestUtils = React.addons.TestUtils
var InputFieldItem = require('../../src/page/name/NamePage')
describe('Name page component', function(){
var renderedComponent;
before('render element', function() {
console.log("*** in before")
renderedComponent = TestUtils.renderIntoDocument(
<InputFieldItem />
);
});
it('Only First Name entered should display one error message', function() {
renderedComponent = TestUtils.renderIntoDocument(
<InputFieldItem />
);
var formElement = TestUtils.findRenderedDOMComponentWithTag(renderedComponent, 'form').getDOMNode()
var firstNameElement = TestUtils.scryRenderedDOMComponentsWithTag(renderedComponent, 'input')[0].getDOMNode()
var lastNameElement = TestUtils.scryRenderedDOMComponentsWithTag(renderedComponent, 'input')[1].getDOMNode()
var buttonElement = TestUtils.findRenderedDOMComponentWithTag(renderedComponent, 'button').getDOMNode()
TestUtils.Simulate.change(firstNameElement , {target: {value: 'Joe'}});
TestUtils.Simulate.submit(formElement)
var errorSpans = TestUtils.scryRenderedDOMComponentsWithClass(renderedComponent, 'error-message')
console.log("First name value is :|"+ firstNameElement.value + "|")
expect (errorSpans.length).to.equal(1)
})
});

Related

Masking Phone in Ember JS

I am trying to mask a Phone number in a input field, can somebody please help me in this regards. Here is my code for the html (or .hbs file)
<label class="control-label">Phone</label>
{{masked-input mask='(999) 999-9999'
value=model.Address.Phone
input-format='regex'
input-filter='\(*[0-9]{3}\) [0-9]{3}-[0-9]{4}'
input-filter-message='Phone number is not valid.'
class='form-control phone masked'
maxlength="14"}}
</div>
And my component definition is as below:
export default () => {
IMS.registerComponent("masked-input", {
tagName: 'input',
attrParams: ['required', 'title', 'name', 'placeholder'],
loaded: false,
prop: Ember.observer(
'required',
'title',
'name',
'placeholder',
'value',
function () {
var scope = this;
$(this.element).val(Ember.get(scope, 'value'));
var stamp = new Date();
if (Ember.get(scope, 'loaded') == true) {
var element = $(this.element);
var attrs = Ember.get(this, 'attrParams');
attrs.forEach(function (attr) {
var value = Ember.get(scope, attr);
if (value == '' | value == null) {
element.removeAttr(attr);
} else {
element.attr(attr, value);
}
})
}
}),
observeMask: Ember.observer('mask', function () {
var scope = this;
$(this.element).inputmask({
mask: Ember.get(scope, 'mask')
});
}),
didInsertElement: function () {
var scope = this;
setTimeout(function () {
var value = Ember.get(scope, 'value');
var element = $(scope.element);
var change = function () { Ember.set(scope, 'value', element.val()); }
element.val(Ember.get(scope, 'value'));
element.attr('type', 'text');
element.change(change);
Ember.set(scope, 'loaded', true);
scope.observeChanges();
element.inputmask({
mask: Ember.get(scope, 'mask')
});
element.attr('input-format', Ember.get(scope, 'input-format'));
element.attr('input-filter', Ember.get(scope, 'input-filter'));
element.attr('input-filter-message', Ember.get(scope, 'input-filter-message'));
}, 250);
}
})
}

How to use react semantic ui Dropdown to show number of pages and selected page on right side?

I am new to react. I am following https://www.truecodex.com/course/react-js this example but in this example, it shows all the customers. I want to add a dropdown with no. of pages and on-page selection changes the values in the table.
I think, I should take one more customer{} and add 1-4customer 2-next4customer and then on dropdown selection on change change the table values
Here is my Customer view class where I am fetching all customers.
import React from 'react';
import { Table,Icon, Button } from 'semantic-ui-react';
export default class CustomerView extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
deleteTitle: "customer",
isLoaded: false,
formClose: false,
singleCustomer: [],
users: []
}
}
//fetch data
componentDidMount() {
const customerApi = 'https://localhost:44387/api/Customers';
const myHeader = new Headers();
myHeader.append('Content-type', 'application/json');
myHeader.append('Accept', 'application/json');
myHeader.append('Origin', 'https://localhost:44387');
const options = {
method: 'GET',
myHeader
};
fetch(customerApi, options)
.then(res => res.json())
.then(
(result) => {
this.setState({
users: result,
isLoaded: true
});
},
(error) => {
this.setState({
isLoaded: false,
error
});
}
)
}
//Delete Customer
onDeleteCustomer = customerId => {
const { users } = this.state;
this.setState({
users: users.filter(customer => customer.customerId !== customerId)
});
const customerApi = 'https://localhost:44387/api/Customers/' + customerId;
const myHeader = new Headers({
'Accept': 'application/json',
'Content-type': 'application/json; charset=utf-8'
});
fetch(customerApi, {
method: 'DELETE',
headers: myHeader
})
.then(res => res.json())
.then(
(result) => {
this.setState({
})
}, (error) => {
this.setState({ error });
}
)
}
render() {
const { users } = this.state;
return (
<div>
<Button color='blue' onClick={() => this.props.onCreate()}>New Customer</Button>
<br/>
<br/>
<Table celled textAlign='center'>
<Table.Header>
<Table.Row>
<Table.HeaderCell>ID</Table.HeaderCell>
<Table.HeaderCell>Name</Table.HeaderCell>
<Table.HeaderCell>Address</Table.HeaderCell>
<Table.HeaderCell>Action</Table.HeaderCell>
<Table.HeaderCell>Action</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body >
{
users.map(user => (
<Table.Row key={user.customerId}>
<Table.Cell>{user.customerId}</Table.Cell>
<Table.Cell>{user.name}</Table.Cell>
<Table.Cell>{user.address}</Table.Cell>
<Table.Cell>
<Button color='yellow' icon labelPosition='right'
onClick={() => this.props.onEditCustomer(user.customerId)}>
<Icon name='edit outline'/>
Edit</Button>
</Table.Cell>
<Table.Cell>
<Button color='red' icon labelPosition='right'
onClick={() => this.props.onDeleteClick(user.customerId)}>
<Icon name='trash alternate'/>
Delete</Button>
</Table.Cell>
</Table.Row>
))
}
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.HeaderCell colSpan='5'>
No of Pages
</Table.HeaderCell>
</Table.Row>
</Table.Footer>
</Table>
</div>
)
}
}

vue unit test - data not updated after triggering event ( form submit) as expected

I am testing that form data are sent after submit.
ContactForm.spec.js
import Vue from "vue";
import Vuex from "vuex";
import { mount, shallowMount } from "#vue/test-utils";
import VeeValidate from "vee-validate";
import i18n from "#/locales";
import Vuetify from "vuetify";
import ContactForm from "#/components/Home/ContactForm.vue";
Vue.use(VeeValidate, { errorBagName: "errors" });
Vue.use(Vuetify);
Vue.use(Vuex);
describe("ContactForm.vue", () => {
let store;
let wrapper;
let options;
let input;
const v = new VeeValidate.Validator();
beforeEach(() => {
const el = document.createElement("div");
el.setAttribute("data-app", true);
document.body.appendChild(el);
});
it("should sendMessage - valid form", async () => {
// given
store = new Vuex.Store({
state: {
language: "en",
loading: false
}
})
options = {
sync: false,
provide: {
$validator () {
return new VeeValidate.Validator();
}
},
i18n,
store
};
wrapper = mount(ContactForm, options);
// when
const radioInput = wrapper.findAll('input[type="radio"]');
radioInput.at(1).setChecked(); // input element value is changed, v-model is not
radioInput.at(1).trigger("change"); // v-model updated
input = wrapper.find('input[name="givenName"]');
input.element.value = "John"; // input element value is changed, v-model is not
input.trigger("input"); // v-model updated
input = wrapper.find('input[name="familyName"]');
input.element.value = "Doe"; // input element value is changed, v-model is not
input.trigger("input"); // v-model updated
input = wrapper.find('input[name="email"]');
input.element.value = "john.doe#example.com"; // input element value is changed, v-model is not
input.trigger("input"); // v-model updated
input = wrapper.find('textarea[name="messageContent"]');
input.element.value = "Hello World!"; // input element value is changed, v-model is not
input.trigger("input"); // v-model updated
const contactForm = wrapper.find("form");
contactForm.trigger("submit");
await wrapper.vm.$nextTick();
// then
console.log("DATA: ", wrapper.vm.$data.contactLang);
expect(wrapper.vm.validForm).toEqual(true);
});
});
Validation is successful ( so validForm is set to true in the component )
BUT the test does not pass
console.log
✕ should sendMessage - valid form (476ms)
● ContactForm.vue › should sendMessage - valid form
expect(received).toEqual(expected)
Expected value to equal:
true
Received:
false
The component vue is
ContactForm.vue
<template>
<form id="contactForm" #submit="sendMessage()">
<input v-model="contactLang" type='hidden' data-vv-name="contactLang" v-validate="'required'" name='contactLang'>
<v-layout row wrap align-center>
<v-flex xs12 sm3 md3 lg3>
<v-radio-group row :mandatory="false" v-model="gender" name="gender">
<v-radio :label='genderLabel("f")' value="f" name="female"></v-radio>
<v-radio :label='genderLabel("m")' value="m" name="male"></v-radio>
</v-radio-group>
</v-flex>
<v-flex xs12 sm4 md4 lg4>
<v-text-field
v-model="givenName"
browser-autocomplete="off"
:label="$t('lang.views.home.contactForm.givenName')"
data-vv-name="givenName"
:error-messages="errors.collect('givenName')"
v-validate="'required'"
name="givenName">
</v-text-field>
</v-flex>
<v-flex xs12 sm5 md5 lg5>
<v-text-field
v-model="familyName"
browser-autocomplete="off"
:label="$t('lang.views.home.contactForm.familyName')"
data-vv-name="familyName"
:error-messages="errors.collect('familyName')"
v-validate="'required'"
name="familyName">
</v-text-field>
</v-flex>
</v-layout>
<v-text-field
browser-autocomplete="off"
v-model="email"
:label="$t('lang.views.home.contactForm.email')"
data-vv-name="email"
:error-messages="errors.collect('email')"
v-validate="'required|email'"
name="email">
</v-text-field>
<v-textarea v-model="messageContent" :label="$t('lang.views.home.contactForm.message')" :error-messages="errors.collect('messageContent')" :rules="[(v) => v.length <= 200 || 'Max 200 characters']" :counter="200" v-validate="'required'" data-vv-name="messageContent" name="messageContent"></v-textarea>
<v-btn id="btnClear" round #click.native="clear">{{ $t('lang.views.global.clear') }}</v-btn>
<v-btn round large color="primary" type="submit">{{ $t('lang.views.global.send') }}
<v-icon right>email</v-icon><span slot="loader" class="custom-loader"><v-icon light>cached</v-icon></span>
</v-btn>
</form>
</template>
<script>
import swal from "sweetalert2";
import { mapState } from "vuex";
import appValidationDictionarySetup from "#/locales/appValidationDictionary";
export default {
name: "contactForm",
$_veeValidate: { validator: "new" },
data() {
return {
contactLang: "",
gender: "f",
givenName: "",
familyName: "",
email: "",
messageContent: "",
validForm: false
};
},
...
methods: {
...
sendMessage: function() {
console.log("sendMessage()...");
this.$validator
.validateAll()
.then(isValid => {
console.log("VALIDATION RESULT: ", isValid);
this.validForm = isValid;
if (!isValid) {
console.log("VALIDATION ERROR");
// console.log("Errors: ", this.$validator.errors.items.length);
const alertTitle = this.$validator.dictionary.container[
this.language
].custom.error;
const textMsg = this.$validator.dictionary.container[this.language]
.custom.correct_all;
swal({
title: alertTitle,
text: textMsg,
type: "error",
confirmButtonText: "OK"
});
return;
}
console.log("validation success, form submitted validForm: ", this.validForm);
return;
})
.catch(e => {
// catch error from validateAll() promise
console.log("error validation promise: ", e);
this.validForm = false;
return;
});
},
clear: function() {
this.contactLang = "";
this.gender = "f";
this.givenName = "";
this.familyName = "";
this.email = "";
this.messageContent = "";
this.validForm = false;
this.$validator.reset();
}
},
mounted() {
appValidationDictionarySetup(this.$validator);
this.$validator.localize(this.language);
this.contactLang = this.language;
}
};
</script>
</style>
and the console.log debugging is
console.log src/components/Home/ContactForm.vue:90
sendMessage()...
console.log tests/unit/ContactForm.spec.js:242
DATA: en
console.log src/components/Home/ContactForm.vue:94
VALIDATION RESULT: true
It's weird to see that the DATA ( contactLang ) value is false in the console.log from the spec ... displayed before the validation result
console.log src/components/Home/ContactForm.vue:90
sendMessage()...
console.log tests/unit/ContactForm.spec.js:242
DATA: en
console.log src/components/Home/ContactForm.vue:94
VALIDATION RESULT: true
console.log src/components/Home/ContactForm.vue:112
validation success, form submitted validForm: true
I guess there is async problem ... timout ?
thanks for feedback
SOLVED
It's actually a timeout issue
expect.assertions(1); // Otherwise jest will give a false positive
await contactForm.trigger("submit");
// then
setTimeout(() => {
expect(wrapper.vm.validForm).toEqual(true);
}, 2000);
I propose to use jest faketimers
jest.useFakeTimers()
contactForm.trigger("submit");
await wrapper.vm.$nextTick();
// then
jest.runTimersToTime(2000)
expect(wrapper.vm.validForm).toEqual(true);
I suggest to first make the test fail to avoid false positives
for more information about jest faketimers
https://jestjs.io/docs/en/timer-mocks.html
i did a simple test for my login form of component, in case it helps someone
it("submit form call method login", () => {
const login = jest.fn()
const wrapper = shallowMount(Login, {
methods: {
login
}
})
wrapper.findAll("v-form").at(0).trigger("submit")
expect(login).toBeCalled()
})

Optimize JSOM Query

I have the following SharePoint 2016 JSOM query that retrieve the list item based on the current user email...this query currently works, however, I have been doing some study around using jquery defferred and Promised objects. In order to rationalize how this methods works I want to optimize the existing code below
<script type="text/javascript" src="//code.jquery.com/jquery-3.2.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
getCurrent();
//getMyTasks();
$('#checkall').click(function (e) {
$("#GetItems").find('td input:input[name=chk]').prop('checked', this.checked);
if($(this).is(':checked')) {
$('#Reject').removeAttr('disabled');
$('#Approve').removeAttr('disabled');
} else {
$('#Reject').attr('disabled', true);
$('#Approve').attr('disabled', true);
}
});
$('#GetItems').on('change', 'input[name=chk]', function(){
if($(this).is(':checked')) {
$('#Reject').removeAttr('disabled');
$('#Approve').removeAttr('disabled');
} else {
$('#Reject').attr('disabled', true);
$('#Approve').attr('disabled', true);
}
});
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', approve);
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', reject);
// approve();
//reject();
});
function getCurrent()
{
$.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/SP.UserProfiles.PeopleManager/GetMyProperties?$select=Email",
headers: { Accept: "application/json;odata=verbose" },
success: function (data) {
currentEmail=data.d.Email;
getMyTasks();
} ,
error: function (data) {
alert("failed to get email");
}
});
}
function getMyTasks(){
//var listTitle="hardware%20requisition";
var row = "";
var buttonrow="";
var url =_spPageContextInfo.webAbsoluteUrl + "/_api/web/lists/getbytitle('EUS Asset Request')/Items?$select=ID,AssetMgrEmail,EUSPersonMailID,SRNo,AssetAvailability,Asset_x0020_Manager_x0020_Approv,Asset_x0020_Manager_x0020_Commen,Attachments,Department,Department_x0020_Head,Department_x0020_head_x0020_Appr,Department_x0020_head_x0020_appr1,Department_x0020_head_x0020_Appr0,HOD_x0020_Approval_x0020_Comment,IT_x0020_Head,IT_x0020_Head_x0020_Approval_x001,IT_x0020_head_x0020_Approval_x00,Items_x0020_Requested_x0020_For,IT_x0020_head_x0020_approval_x000,IT_x0020_head_x0020_Approved_x00,Job_x0020_Title,L1_x0020_Approval_x0020_Comments,L1_x0020_Approval_x0020_Date,L1_x0020_Approval_x0020_Status,L1_x0020_Approved_x0020_Date,L1_x0020_Supervisor_x0020_Email,Motivation,OPCO,Replacement_x0020_Type,Request_x0020_Summary,Request_x0020_Type,Requester_x0020_Name,EUSPersonMailID,Requester_x0020_Phone_x0020_Numb,ViewID,Author/Name,Author/EMail,Author/Title&$expand=Author/Id&$filter=EUSPersonMailID eq '"+currentEmail+"' and L1_x0020_Approval_x0020_Status eq 'Approved' and Department_x0020_head_x0020_appr1 eq 'Approved' and IT_x0020_head_x0020_approval_x000 eq 'Approved' and Asset_x0020_Manager_x0020_Approv eq 'Approved' and EUSTeamConfirmation eq 'Pending'"
$.ajax({
url: url,
type: "GET",
headers:
{
"Accept": "application/json;odata=verbose",
"Content-Type": "application/json;odata=verbose",
},
success: function(data){
var result = data.d.results;
if(result.length>0)
{
$("#divbuttons").show();
$.each(result, function(key, item)
{
var createdDate= moment(item.Created_x0020_Date).format("DD/MM/YYYY");
row = row + '<tr style="background-color: #cccccc;"><td style="width: 261.6px;"><strong>Select</strong> <input name="chk" type="checkbox" value='+ item.Id+' /></td><td style="width: 151.2px;"> </td><td style="width: 324.8px;"><strong>Request ID: </strong>'+item.ID+'</td><td style="width: 324.8px;"><strong>Requester Name: </strong>'+item.Author.Title+'</td><td style="width: 376.8px;"><strong>Phone Number:</strong><br />'+item.Requester_x0020_Phone_x0020_Numb+'</td><td style="width: 396px;"><strong>Department:</strong><br />'+item.Department+'</td><td style="width: 213px;"><strong>Request Type</strong><br />:'+item.Request_x0020_Type+'</td><td style="width: 4.8px;">Availability Status<br/>:'+item.AssetAvailability+'</td><td style="width: 213px;"><strong>Serial Number</strong><br />'+item.SRNo+'</td><td style="width: 213px;"><strong>EUS Person MailID</strong><br />'+item.EUSPersonMailID+'</td><td style="width: 213px;"><strong>Receiver MailID</strong><br />'+item.Author.EMail+'</td></tr>';
})
$("#GetItems>tbody").html(row);
$("#GetItems").show();
}
else{
$("#NoTask").show();
}
},
error: function(data){
alert("Failed to get list items.");
}
});
}
function approve(){
$("#Approve").click(function(event){
event.preventDefault();
var searchIDs = $("#GetItems input:checkbox:checked").map(function(){
return $(this).val();
}).get();
var itemArray = [];
var clientContext = new SP.ClientContext(_spPageContextInfo.webAbsoluteUrl);
var oList = clientContext.get_web().get_lists().getByTitle("EUS Asset Request");
for(var i = 0; i< searchIDs.length; i++){
// alert($("#GetItems textarea#"+searchIDs[i]+"").val());
var oListItem = oList.getItemById(searchIDs[i]);
oListItem.set_item('EUSTeamConfirmation', 'Confirmed');
oListItem.set_item('ViewID', 'FinalVw');
oListItem.update();
itemArray[i] = oListItem;
clientContext.load(itemArray[i]);
}
clientContext.executeQueryAsync(onQuerySucceeded, onQueryFailed);
function onQuerySucceeded() {
alert('Items Updated');
location.reload(true);
}
function onQueryFailed(sender, args) {
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
location.reload(true);
}
});
}
function reject(){
$("#Reject").click(function(event){
event.preventDefault();
var searchIDs = $("#GetItems input:checkbox:checked").map(function(){
return $(this).val();
}).get();
var itemArray = [];
var clientContext = new SP.ClientContext(_spPageContextInfo.webAbsoluteUrl);
var oList = clientContext.get_web().get_lists().getByTitle("EUS Asset Request");
for(var i = 0; i< searchIDs.length; i++){
var oListItem = oList.getItemById(searchIDs[i]);
oListItem.set_item('EUSTeamConfirmation', 'Rejected');
oListItem.set_item('ViewID', 'RejectVw');
oListItem.update();
itemArray[i] = oListItem;
clientContext.load(itemArray[i]);
}
clientContext.executeQueryAsync(onQuerySucceeded, onQueryFailed);
function onQuerySucceeded() {
alert('Task Rejected');
location.reload(true);
//getCurrent();
}
function onQueryFailed(sender, args) {
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
location.reload(true);
// getCurrent();
}
});
}
</script>
<div id="NoTask" style="display:none">You don't have pending tasks for approval</div>
<div style="display:none" id="divbuttons"><input type="checkbox" id="checkall"></input><button type="button" id="Reject" disabled>Reject</button><button type="button" id="Approve" disabled>Approve</button></div>
<table id="GetItems" cellspacing="12"><tbody></tbody> </table>
Kindly assist

Custom Autocomplete Component Ember Cli not working

I not sure why the return is not being passed to the component template. It's listening and the value is found but its not working.
return result.resources; is not returning the data when result.resoures has an array of objects.
here is the autocomplete template auto-complete.hbs
<ul>
<li class='row input-group-lg'>
{{input type="text" value=searchText placeholder="Enter Street Address" class='col-md-6 col-md-offset-3 col-xs-12 street-address'}}
</li>
</ul>
<ul>
{{#each searchResults}}
<li>{{this.name}}</li>
{{/each}}
</ul>
here is auto-complete.js
import Ember from 'ember';
export default Ember.Component.extend({
searchText: null,
searchResults: function() {
var searchText = this.get('searchText');
if(!searchText) {
return;
}
Ember.$.ajax({
url: "http://dev.virtualearth.net/REST/v1/Locations",
dataType: "jsonp",
data: {
key: "",
q: searchText
},
jsonp: "jsonp"
}).then(function(data) {
var result = data.resourceSets[0];
if (result) {
if (result.estimatedTotal > 0) {
return result.resources;
}
}
});
}.property('searchText')
});
The code block
.then(function(data) {
var result = data.resourceSets[0];
if (result) {
if (result.estimatedTotal > 0) {
return result.resources;
}
}
will return from the promise and will not return the value for the computed property, which obviously means that you are not returning anything for the CP.
A possible work around can be
searchResults: function() {
var searchText = this.get('searchText');
var searchResults = Ember.ArrayProxy.create();
if(!searchText) {
return;
}
Ember.$.ajax({
url: "http://dev.virtualearth.net/REST/v1/Locations",
dataType: "jsonp",
data: {
key: "",
q: searchText
},
jsonp: "jsonp"
}).then(function(data) {
var result = data.resourceSets[0];
if (result) {
if (result.estimatedTotal > 0) {
searchResults.set('content',result.resources);
}
}
});
return searchResults;
}.property('searchText')
You can create an arrayproxy and return the arrayproxy for the CP. Upon completion of the promise, set the result as content to the arrayproxy, which will update the template.