Syntax error in AngularJS directive implementation - javascript

I'm trying to change an ng-click event by loading an item.list with the command inside my main app.js file. The item.list looks something like this:
$scope.list = [
{
label: 'Controls',
icon: 'fa fa-sliders fa-fw 4x',
name: 'Controls',
link: '#/ctrlPage',
move: 'console.log("On control page.")'
},
{
label: 'Lights',
icon: 'fa fa-film fa-fw 4x',
name: 'Lights',
link: '#/lightPage',
move: 'connection.send("control Closer");'
},
{
label: 'Queue',
icon: 'fa fa-users fa-fw 4x',
name: 'Queue',
link: '#/queuePage',
move: 'connection.send("control Closer");'
},
{
label: 'Settings',
icon: 'fa fa-cogs fa-fw 4x',
name: 'Settings',
link: '#/settingsPage',
move: 'connection.send("control Closer");'
}
On my index.html page, I have this setup:
<md-list>
<md-list-item ng-repeat="item in list" md-ink-ripple="#3F51B5" class="pointer">
<a href='{{item.link}}' ng-click='{{item.move}}'>
<span aria-label="{{item.label}}" class="{{item.icon}} icon"></span>
{{item.name}}
</a>
</md-list-item>
</md-list>
I can't seem to get it to work, getting this error upon loading the page:
Error: [$parse:syntax] Syntax Error: Token '{' invalid key at column 2 of the expression [{{item.move}}] starting at [{item.move}}].
http://errors.angularjs.org/1.4.8/$parse/syntax?p0=%7B&p1=invalid%20key&p2=2&p3=%7B%7Bitem.move%7D%7D&p4=%7Bitem.move%7D%7D
at http://localhost:3000/bower_components/angular/angular.js:68:12
at Object.AST.throwError (http://localhost:3000/bower_components/angular/angular.js:13100:11)
at Object.AST.object (http://localhost:3000/bower_components/angular/angular.js:13087:16)
at Object.AST.primary (http://localhost:3000/bower_components/angular/angular.js:12995:22)
at Object.AST.unary (http://localhost:3000/bower_components/angular/angular.js:12983:19)
at Object.AST.multiplicative (http://localhost:3000/bower_components/angular/angular.js:12970:21)
at Object.AST.additive (http://localhost:3000/bower_components/angular/angular.js:12961:21)
at Object.AST.relational (http://localhost:3000/bower_components/angular/angular.js:12952:21)
at Object.AST.equality (http://localhost:3000/bower_components/angular/angular.js:12943:21)
at Object.AST.logicalAND (http://localhost:3000/bower_components/angular/angular.js:12935:21) <a href="{{item.link}}" ng-click="{{item.move}}">
Am I missing something, or is what I'm attempting an illegal action?

You don't need {{}}.
Try:
ng-click='item.move()'
Also your move value is text. It should be a function:
{
label: 'Controls',
icon: 'fa fa-sliders fa-fw 4x',
name: 'Controls',
link: '#/ctrlPage',
move: function() {
console.log("On control page.")
}
},

You should do it like this
ng-click="item.move()"
{{ }} are used for "printing out", so what you did is you inserted value that is returned from item.move() into ng-click=""

I think you need to change your move field from string to function, like
$scope.list = [{
label: 'Controls',
icon: 'fa fa-sliders fa-fw 4x',
name: 'Controls',
link: '#/ctrlPage',
move: function() {
console.log("On control page.");
}
}];
and then, in html use
ng-click="item.move()"

Another thing you could do is create a helper function in the controller:
$scope.executeCode(code) {
eval(code);
}
then in the template pass the function contents to it:
ng-click="executeCode(item.move)"
Note: the eval function isn't the greatest thing to use but this will get the job done given your data.
Here's a plnkr: http://plnkr.co/edit/pVQaBul6E3nO8oWY5vxS?p=preview

Related

Save Alert text input into database from ionic alert

I have created an ionic alert to decline a request. I want the user to input a reason for declining the request before they hit confirm. I then would like to save this data into my database and have a method (declineRequest) setup to do so.
The method is working for declining the request. The issue is how to save the alert 'Notes' input field into the database, and how to make sure the declineRequest method is only run when 'confirm' is clicked.
Here is the code:
The HTML:
<ion-list>
<ion-card *ngFor="let r of requests; let i = index">
<ion-item>
<h2>{{r.userId}}</h2>
<p>{{r.requestDetail}}</p>
<p>{{r.fromDateTime}} to {{r.toDateTime}}</p>
<p>{{r.type}}</p>
</ion-item>
<ion-card-content>
<button class="approve" ion-button icon-left color="secondary" (click)="approveAlert(r.id)">
<ion-icon name="checkmark"></ion-icon>
Approve
</button>
<button class="decline" ion-button icon-left color="danger" (click)="declineAlert(r.id)">
<ion-icon name="close"></ion-icon>
Decline
</button>
</ion-card-content>
</ion-card>
</ion-list>
The TS:
declineAlert(requestId) {
const alert = this.alertCtrl.create({
title: 'Confirm Request Declined',
subTitle: 'Notes:',
inputs: [
{
name: "Note",
type: "text",
placeholder: 'Please enter reasons'
}],
buttons: [ { text:"Cancel"
},
{ text: "Confirm",
handler: data => {
console.log(JSON.stringify(data));
console.log(data.Note);
}
}],
cssClass: 'alertCustomCss'
});
alert.present();
console.log(requestId);
let notes = Note;
this.declineRequest(requestId, notes);
}
I have tried different methods but cannot seem to get the text from the decline 'notes' to save.
Any help would be greatly appreciated.
As Keval pointed out you just need to use your method inside the handler like so:
declineAlert(requestId) {
const alert = this.alertCtrl.create({
title: 'Confirm Request Declined',
subTitle: 'Notes:',
inputs: [
{
name: "Note",
type: "text",
placeholder: 'Please enter reasons'
}],
buttons: [ { text:"Cancel"
},
{ text: "Confirm",
handler: data => {
this.declineRequest(requestId, data.Note);
// additional steps like pop() page etc
}
}],
cssClass: 'alertCustomCss'
});
alert.present();
}
Try with my working code
let alert = this.alertCtrl.create({
title: 'Confirm Request Declined',
inputs: [
{
type: 'textarea',
name: 'Message',
placeholder: 'Please enter reasons',
},
],
buttons: [
{
text: 'Yes',
handler: data => {
var message = data.Message;
//Here is Api call
}
},
{
text: 'No',
role: 'cancel',
handler: data => {
var message = data.Message;
//Your logic
}
}
]
});
alert.present();

How to repeat a click handler in ngRepeat (AngularJS)?

I have the following problem. I wanna repeat menu links. But the program doesn't create the corresponding click handler.
View:
//view is created by Angular Material
<md-menu-item ng-repeat="mItem in ::menuItems">
<md-button ng-click="mItem[action]">
<md-icon>{{ ::mItem.icon }}</md-icon>
{{ ::mItem.name }}
</md-button>
</md-menu-item>
Ctrl:
$scope.menuItems = [
{ icon: 'mode_edit', name: 'Edit', action: 'clickEdit()' },
{ icon: 'delete', name: 'Delete', action: 'clickDelete()' }
];
$scope.clickEdit = clickEdit;
$scope.clickDelete = clickDelete;
function clickEdit() {
$log.info('edit clicked');
}
function clickDelete() {
//code...
}
What I need to do to get the handlers in ngClick?
I think it's best to keep that logic in a service like this:
//view is created by Angular Material
<md-menu-item ng-repeat="mItem in ::menuItems">
<md-button ng-click="action(mItem.action)">
<md-icon>{{ ::mItem.icon }}</md-icon>
{{ ::mItem.name }}
</md-button>
</md-menu-item>
$scope.menuItems = [
{ icon: 'mode_edit', name: 'Edit', action: 'edit' },
{ icon: 'delete', name: 'Delete', action: 'delete' }
];
$scope.action = function(actionName){
// call service
}

How can I formatMessage with a tags (links) using react-intl?

I need to add links to the text I need translated. How can I formatMessages that have links?
Right now this is what I am trying to do:
const messages = defineMessages({
copy: {
id: 'checkout.OrderReview.copy',
description: 'Label for add card button',
defaultMessage: 'By clicking the "Place Order" button, you confirm that you have read, understood, and accept our {termsAndConditionsLink}, {returnPolicyLink}, and {privacyPolicyLink}.',
},
termsAndConditions: {
id: 'checkout.OrderReview.termsAndConditions',
description: 'Label for terms and conditions link',
defaultMessage: 'Terms and Conditions',
},
returnPolicy: {
id: 'checkout.OrderReview.returnPolicy',
description: 'Label for return policy link',
defaultMessage: 'Return Policy',
},
privacyPolicy: {
id: 'checkout.OrderReview.privacyPolicy',
description: 'Label for privacy policy link',
defaultMessage: 'Privacy Policy',
},
});
Then, in the render function:
const copy = formatMessage(messages.copy, {
termsAndConditionsLink: `${formatMessage(messages.termsAndConditions)}`,
returnPolicyLink: `${formatMessage(messages.returnPolicy)}`,
privacyPolicyLink: `${formatMessage(messages.privacyPolicy)}`,
});
return <div> { copy } </div>
This doesn't work. I get:
By clicking the "Place Order" button, you confirm that you have read, understood, and accept our [object Object], [object Object], and [object Object].
What is the correct way to accomplish this task?
First, it depends on your react-intl version.
I've made it work using react-intl v2.x (2.8 to be exact). Here's how I did:
const messages = defineMessages({
copy: {
id: 'copy',
defaultMessage: 'Accept our {TermsAndConditionsLink}',
},
termsAndConditions: {
id: 'termsAndConditions',
defaultMessage: 'Terms and conditions',
},
termsAndConditionsUrl: {
id: 'termsAndConditionsUrl',
defaultMessage: '/url',
},
});
<FormattedMessage
{...messages.copy}
values={{
TermsAndConditionsLink: (
<a href={intl.formatMessage(messages.termsAndConditionsUrl)}>
{intl.formatMessage(messages.termsAndConditions)}
</a>
),
}}
/>
For newer react-intl version, you can find your answer in the docs:
v3.x:
https://formatjs.io/docs/react-intl/upgrade-guide-3x#enhanced-formattedmessage--formatmessage-rich-text-formatting
v4.x:
https://formatjs.io/docs/react-intl/api/#formatmessage
<FormattedMessage
id="footer.table_no"
defaultMessage="Hello {link}"
values={{ link: World }}
/>
Can you use the FormattedHTMLMessage component?
const messages = defineMessages({
copy: {
id: 'checkout.OrderReview.copy',
description: 'Label for add card button',
defaultMessage: 'By clicking the "Place Order" button, you confirm that you have read, understood, and accept our {termsAndConditionsLink}, {returnPolicyLink}, and {privacyPolicyLink}.',
},
termsAndConditions: {
id: 'checkout.OrderReview.termsAndConditions',
defaultMessage: 'Terms and Conditions',
},
});
const Component = () => <FormattedHTMLMessage {...{
...messages.copy,
values: {
termsAndConditionsLink: <FormattedHTMLMessage {...messages. termsAndConditions} />
}
} />

unsure why ng-click isn't working

Hey there I'm new to js Angular and can't figure out what I've done wrong, how do I put an object method inside the ng-click function:
<div class="container" ng-repeat="exercise in exercises">
<div class="row">
<div class="exercise-icon col-xs-2">
<img ng-src="{{ exercise.icon }}">
</div>
<div class="col-xs-6">
<p class="exercise-name"> {{ exercise.name }} </p>
</div>
<div class="col-xs-4 counters">
<span class="decrease">-</span><span class="count"> {{ exercise.count }} </span>
<span class="increase" ng-click="{{exercise.increase($index)}}">+</span>
</div>
</div>
This is the controller script:
app.controller('MainController', ['$scope', function($scope) {
$scope.exercises = [
{
icon: 'img/pushup.jpg',
name: 'Pushups',
count: 20
},
{
icon: 'img/squat.jpg',
name: 'Squats',
count: 15
},
{
icon: 'img/pullup.jpg',
name: 'Pullups',
count: 10
},
{
icon: 'img/row.jpg',
name: 'Rows',
count: 10
},
{
icon: 'img/lunge.jpg',
name: 'Lunges',
count: 10
},
{
icon: 'img/stepup.jpg',
name: 'Step Ups',
count: 10
},
{
icon: 'img/situp.jpg',
name: 'Sit Ups',
count: 15
}
];
$scope.increase = function($index) {
$index.count++;
};
}]);
The exercise icon, name and count are all showing however the click function is not working for some reason, is the syntax correct for inserting a object method into a ng-click? I couldn't find any applicable answers online.
The functionality I would expect is count to increase everytime + is pressed.
There are 2 points wrong here, you're calling your function wrongly:
{{exercise.increase($index)}}
should be
increase($index)
and you're treating $index as an object, it should be like so:
$scope.increase = function($index) {
$scope.exercises[$index].count++;
};
Change:
<span class="increase" ng-click="{{exercise.increase($index)}}">+</span>
to:
<span class="increase" ng-click="exercise.increase($index)">+</span>
The braces aren't needed in Angular.
You can achieve your result without calling a function and doing stuff just inside ng-click itself.
<span class="increase" ng-click="exercises.count =exercises.count+1 ">+</span>
try this one
<span class="increase" ng-click="increase($index)">+</span>
and you controller
$index = $index + 1;

AngularJS ng-click to go to view

Hi I have a button that I have a ng-click directive on that I just want to load a view. I've looked at some pages online, and I'm not able to figure out how to get the button to work. My button looks like this:
<button class="btn default-btn lookupbtn" ng-click="go('/lookup')">Lookup</button>
and my controller like this:
(function () {
'use strict';
angular.module('crm.ma').controller('LookUpCtrl', LookUpCtrl, function($location){
function LookUpCtrl() {
var vm = this;
vm.results = [
{
accountId: 1,
accountName: 'some name',
address: '201 some st',
city: 'Columbus',
state: 'OH',
zip: 'zip',
phone: '899-629-7645',
parentName: 'Parent 1',
accountType: 'Type 1',
accountStatus: 'Status 1',
creditTerm: 'Term 1'
},
{
accountId: 2,
accountName: 'house home',
address: '2963 this st',
city: 'Columbus',
state: 'OH',
zip: 'zip',
phone: '899-627-7592',
parentName: 'Parent 2',
accountType: 'Type 2',
accountStatus: 'Status 2',
creditTerm: 'Term 2'
}
];
vm.go = function (path) {
$location.path(path);
};
}
})
}());
I'm really new to Angular and I'm just not sure what I'm doing wrong. If any other code is needed please let me know. Thanks.
Instead of that you could convert that button to anchor & apply the CSS classes of button of bootstrap, that will give you look and fill of button it & then use ng-href attribute to have redirection URL on it inside SPA.
<a class="btn btn-md" ng-href="#/lookup">Lookup</a>
Additionally as #charlietfl suggested you need to add missing dependency of $location, $scope would also needs to add if you are following the second way.
Controller definition is incorrect. Should look like:
angular
.module('crm.ma')
// only 2 arguments, name and function
.controller('LookUpCtrl', LookUpCtrl);
// add the dependency injections to function
function LookUpCtrl($location) {
var vm = this;
vm.results = [... ];
vm.go = function (path) {
$location.path(path);
};
}
Then for go() you have no function go() in your controller and if you did you wouldn't use a leading / for $state.go()
Can use ui-sref to point to a state in html if using ui-router:
<a class="btn btn-md" ui-sref="lookup">Lookup</a>

Categories

Resources