ng-switch-when-separator not working in angularJS - html

ng-switch is not working when i use ng-switch-when-separator .
when I select settings the switch is pointing to default div
angular.module("myModule", [])
.controller("myController", function ($scope) {
$scope.items = ['settings', 'home', 'options', 'other'];
$scope.opt = $scope.items[0];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myModule">
<div ng-controller="myController">
<select ng-model="opt" ng-options="item for item in items">
</select>
<code>selection={{opt}}</code>
<hr />
<div class="animate-switch-container"
ng-switch on="opt">
<div class="animate-switch" ng-switch-when="settings|options" ng-switch-when-separator="|">Settings Div</div>
<div class="animate-switch" ng-switch-when="home">Home Span</div>
<div class="animate-switch" ng-switch-default>default</div>
</div>
</div>
</body>

This is an issue with the documentation page, but not a bug in Angular itself.
What happens:
The docs by default show the API for the current master branch (also called snapshot)
the embedded plnkrs also use the built angular files from the master branch
the automatically created plnkrs fall back to the latest stable version (in that case 1.5.8) which doesn't support the separator yet.
So you'll have to wait for 1.5.10 to use that feature.

Related

Nodejs Stripe how to dynamically pass the Stripe price ID to my server after clicking the purchase button of an item

I am working on my first dynamic website using HTML, Express & node.js. Reading through the Stripe documentation and other sources I've come across various examples but my main goal is to use my Stripe API key and each item price ID's in my server and not in my front end code so no one can temper with them. I've successfully use my Stripe API key on my backend and used the .post method to redirect the user after pressing the Buy Now button to the checkout page as shown below:
Node.js
const stripe = require('stripe')('sk_test_key');
const express = require('express');
const app = express();
app.use(express.static('public'));
const YOUR_DOMAIN = 'http://localhost:4242';
app.post('/create-checkout-session', async (req, res) => {
const session = await stripe.checkout.sessions.create({
line_items: [
{
price: 'price_priceKey',
quantity: 1,
},
],
mode: 'payment',
success_url: `${YOUR_DOMAIN}/success.html`,
cancel_url: `${YOUR_DOMAIN}/cancel.html`,
});
res.redirect(303, session.url);
});
app.listen(4242, () => console.log('Running on port 4242'));
HTML
<!DOCTYPE html>
<html>
<head>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-iYQeCzEYFbKjA/T2uDLTpkwGzCiq6soy8tYaI1GyVh/UjpbCx/TYkiZhlZB6+fzT"
crossorigin="anonymous"
/>
<title>Product Page</title>
<link rel="stylesheet" href="style.css" />
<script src="https://js.stripe.com/v3/"></script>
</head>
<body>
<div class="row">
<div class="col-lg-6">
<section>
<div class="product">
<img
class="collar-img"
src="image"
alt="product-image"
/>
<div class="description">
<h3>Leather Collar</h3>
<h5>$9.99</h5>
</div>
</div>
<form action="/create-checkout-session" method="POST">
<button type="submit" id="checkout-button">Checkout</button>
</form>
</section>
</div>
<div class="col-lg-6">
<section>
<div class="product">
<img
class="collar-img"
src="image2"
alt="product-image2"
/>
<div class="description">
<h3>Comsos Collar</h3>
<h5>$19.99</h5>
</div>
</div>
<form action="/create-checkout-session" method="POST">
<button type="submit" id="checkout-button">Buy Now</button>
</form>
</section>
</div>
</div>
</body>
</html>
My problem is I've only figure how to hardcode the price ID for a product inside my line_items object in node.js so when the user clicks the Buy Now button it will only add to the checkout page the items that I added. I've come across examples of adding the price ID to the attribute "data-price-id" inside each button element so that each item has a button that contains its correct price but that exposes all my price ID's to my frontend code. I already tried hiding the ID in my frontend using EJS and the dotenv module in node.js but this was futile. I would really appreciate if someone could point me the right direction or sample code on how to pass these different price ID's after user clicks on each button of each item back to my server.
It's okay to expose the Price IDs to the front-end code. Nobody can do anything with those Prices without access to your API keys, so it's okay if they show up on the front-end.
That being said, you can dynamically pass an ID from back-end to front-end via a number of different methods. The one I would recommend would be document.querySelector()[0]. This allows you to dynamically set an HTML element's value using Javascript.
An example might look like this: document.querySelector("#price-id").value = somePriceID;
The above snippet looks for an HTML element called price-id and assigns the value from the somePriceID variable to it.
[0] https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
I see you're not using a DB.
One approach you could make is just create an object on the server such as:
const PRODUCT_IDS = {
toaster-x1000: {
price_id: 'toaster-price-id'
}
};
That way, you can just use your own codes on the HTML sites and find the Stripe code on the backend when you need it.
For example, if they want the toaster, you would send "toaster-x1000" and just grab that ID from the list:
const ID_RECEIVED = "toaster-x1000";
const CORRECT_STRIPE_ID = PRODUCT_IDS[ID_RECEIVED].price_id;
That would give you the price id you need for the API call.

ng-if and ng-show in my Ionic application, neither works

The html code goes something like this:
<div ng-if="name=='John'">
<div class="item item-avatar"> <img ng-src="john.jpg"></div>
</div>
<div ng-if="name=='Margaret'"
<div class="item item-avatar"> <img ng-src="margaret.jpg"></div>
</div>
Instead of ng-if, I've tried using ng-show as well. Neither worked. Both John as well as Margaret showed on the page no matter which I used. I tried with ng-switch also.
The variable 'name' I initialized earlier on the same HTML file as:
<a class="item item-avatar item-icon-right" ng-init="name = 'John'" href = "#/Page3"></a>
Clicking on the above line leads to Page3 where I need to display either John or Margaret depending on the value of 'name'.
Is the syntax wrong or something, because that could be very well possible. I'm new to Ionic and AngularJS.
Try this:
<div ng-show="name=='John'" ng-init="name = 'John'">
<div class="item item-avatar"> John</div>
</div>
<div ng-show="name=='Margaret'"
<div class="item item-avatar"> Margaret</div>
</div>
Works for me. I just change ng-if to ng-show - which will shows div content when true and hide it otherwise. I also use ng-init inside a div.
Are you sure you started Angular? Did you set the ng-app directive?
It would help if you could provide a working example if you have other problems.
angular.module('app', []);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-init="name = 'John'">
<button type="button" ng-click="name='John'">John</button>
<button type="button" ng-click="name='Margaret'">Margaret</button>
<div ng-if="name=='John'">
This is John
</div>
<div ng-if="name=='Margaret'">
This is Margaret
</div>
</div>
I fixed you plunker - now it should be working.
Bug #1: ng-init is for initialization not to set values at runtime -> use ng-click instead
Bug #2: You use the same controller for all pages but for each page a new controller will be initialized, which resets the 'name' property
I implemented a setName function to set the name in the rootscope and to go to page3. In a correct implementation you should pass the name as a $stateparam to the new state/page. But for that please have a look at the ui-router documentation.
$scope.setName = function(name) {
console.log(name);
$rootScope.name = name;
$state.go('Page3');
};

Show an ngMessage if ngOptions array is empty

Is it possible to use ngMessages to show an error while initializing options of a select element using ngOptions?
For ex. in
<select name="fruitNames" ng-model="fruitName" ng-options="fruit.name for fruit in fruits"></select>
if fruits is empty, I want to show an error message.
You could provide any expression to ng-messages as a kvp, example i am setting boolean value to hasFruits and using the key hasFruits.
<div ng-messages="{noFruits:!fruits.length}" >
<div ng-message="noFruits">Sorry, No fruits available!!</div>
</div>
angular.module('app', ['ngMessages']).controller('ctrl', function($scope) {
$scope.fruits = [];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-messages.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div ng-messages="{hasFruits:!fruits.length}">
<div ng-message="hasFruits">No fruits available!!</div>
</div>
</div>
This however seems a bit weird since you really don't have multiple conditions here (Unlike the way you use ngMessages with $error object), you could just show and hide a div as well instead.

angularjs template ng-view

Anyone can please tell me what im doing wrong here:
i just update the library, and seems that the code broke for some reason it's not doing anything.
angular library
html5 code
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
<header id="header">
<h1 id="logo"></h1>
<div id="menu">
<a ng-click="setRoute('home')" class="btn">Home</a>
<a ng-click="setRoute('about')" class="btn">about</a>
<a ng-click="setRoute('experiments')" class="btn">Experiments</a>
</div>
<div class="color"></div>
<div class="clear"></div>
</header>
<!-- //top -->
<div class="shadow"></div>
<div id="container">
<div ng-view></div>
</div>
angular.js
angular.module('WebSite', []).
config(function($routeProvider) {
$routeProvider.
when('/about', {templateUrl:'folder/test.html', controller:AboutCtrl}).
when('/experiments', {templateUrl:'folder/test.html', controller:ExperimentsCtrl }).
when('/home', {templateUrl:'folder/test.html', controller:HomeCtrl }).
otherwise({redirectTo:'/home'});
});
function AboutCtrl($scope) {
$scope.title = 'About Page';
$scope.body = 'This is the about page body';
}
function ExperimentsCtrl($scope) {
$scope.title = 'Experiments Page';
$scope.body = 'This is the about experiments body';
}
function HomeCtrl($scope) {
$scope.title = 'Home Page';
$scope.body = 'This is the about home body';
}
First you need to use ng-app to setup the angular application with your module. Maybe you already did, but it is not part of the snippet you posted:
<html ng-app="WebSite">
Also, about the setRoute(), I don't know where you copy that from, but you don't need it. Just use the href with the hash, for example:
about
You need to check out the source from github at https://github.com/simpulton/angular-website-routes
There is no changeRoute method. After some dialog, I realized it was best to handle the anchors tags as naturally as possible.
Your menu element should look like this
<div id="menu">
Home
About
Experiments
</div>
Hope this helps!

Angular JS - Having an empty array

I have a form that submits data into a function called ng-submit="newBirthday() this pushes data - $scope.bdayname, $scope.bdaydate; into an array called bdaes
My issue is that with all of the tutorials I have seen the array has predefined data is there a way that it can be an empty array that gets filled with data when it is submitted?
app.js:
var app = angular.module('birthdayToDo', []);
app.controller('main', function($scope){
// Start as not visible but when button is tapped it will show as true
$scope.visible = false;
// Create the array to hold the list of Birthdays
$scope.bdays = [{}];
// Create the function to push the data into the "bdays" array
$scope.newBirthday = function(){
$scope.bdays.push({name:$scope.bdayname, date:$scope.bdaydate});
$scope.bdayname = '';
$scope.bdaydate = '';
}
});
HTML:
<body ng-app="birthdayToDo" ng-controller="main">
<div id="wrap">
<!-- Begin page content -->
<div class="container">
<div class="page-header">
<h1>Birthday Reminders</h1>
</div>
<ul ng-repeat="bdays in bdays">
<li>{{bdae.name}} | {{bdae.date}}</li>
</ul>
<form ng-show="visible" ng-submit="newBirthday()">
<label>Name:</label>
<input type="text" ng-model="bdayname" placeholder="Name"/>
<label>Date:</label>
<input type="date" ng-model="bdaydate" placeholder="Date"/>
<button class="btn" type="submit">Save</button>
</form>
</div>
<div id="push"></div>
</div>
<div id="footer">
<div class="container">
<a class="btn" ng-click="visible = true"><i class="icon-plus"></i>Add</a>
</div>
</div>
<script type="text/javascript" src="js/cordova-2.5.0.js"></script>
<script type="text/javascript">
app.initialize();
</script>
</body>
Okay, there were a few of small issues.
An empty array must have no items; [{}] is an array with one item: an empty object. Changing to [] gets rid of the extra bullet.
The bigger issue was your ngRepeat. You used ng-repeat="bdays in bdays". What ngRepeat does is take an array and allow you to do a "for each" on the array, assigning each value to that temporary local variable. You named them the same. Instead, ng-repeat="bday in bdays" will add the DOM nodes inside of it for each item in bdays, giving you a local variable called bday to use to reference each item.
Inside the ngRepeat template, you used bdae, which doesn't reference anything.
I don't know what app.initialize() is, so I removed it. It was just erroring out in the console.
Here's a fixed Plunker: http://plnkr.co/edit/OFWY7o?p=preview