My scope apply isn't working correctly - angularjs

I have tried to research this issue and have had no luck. My ng-repeat doesn't display dynamic content from the controller on the first try. I was told to use a .digest or apply to get angular to hit my page again but I am not quite clear how to implement. From the examples I saw online this should work
var shopItems = angular.module('shopItems', []);
var trophyEarns = angular.module('trophyEarns', []);
var app = angular.module('app', ['shopItems', 'trophyEarns']);
shopItems.controller('shopItemController', function ($scope) {
$scope.shopItems = [{
//id: 01,
name: 'One',
//img: '',
price: '$3.99',
altprice: '1 mile',
desc: 'This is a fake description.',
prog: '50%'
},{
//id: 02,
name: 'Two',
//img: '',
price: '$3.99',
altprice: '1 mile',
desc: 'This is a fake description.',
prog: '50%'
}];
$scope.$apply();
});
trophyEarns.controller('trophyEarnsController', function ($scope) {
$scope.trophyEarns = [{
//id: 01,
name: 'One',
//img: '',
price: '$3.99',
altprice: '1 mile',
desc: 'This is a fake description.',
prog: '50%'
},{
//id: 02,
name: 'Two',
//img: '',
price: '$3.99',
altprice: '1 mile',
desc: 'This is a fake description.',
prog: '50%'
}];
$scope.$apply();
});
Here is a snippet of the html and controller
<div ng-app="app">
<div ng-controller="shopItemController">
<div class="itm" ng-repeat="shopItem in shopItems">
<div class="imag"></div>
<h2>{{ shopItem.name }}</h2>
<div class="hff">Earn it: {{ shopItem.altprice }}</div>
<div class="hf">Buy it: {{ shopItem.price }}</div>
<div class="desc"><div>{{ shopItem.desc }}</div></div>
<div class="prog"><div>{{ shopItem.progress }}</div></div>
</div>
</div>
</div>
But this does nothing and no errors pop up. I am still forced to reload every time I leave and go back to the pages with the controllers to see the dynamic content. Am I using this correctly? Is digest better?

Related

VueJs v-for loop an array inside an array

I have a code as
<div v-for="benefit in service.benefits">
<p>{{benefit}}</p>
</div>
and here is the data
service: [
{title: 'blablabla',
price: '123',
benefits: ['a', 'b']},
{title: 'blaaablabla',
price: '12345',
benefits: ['aa', 'bb']},
]
I want to loop the data inside the benefits, but it doesn't work because v-for needs a key and in my case, there's no key for that. Is there any other way to loop this kind of data?
Thank you
you can use v-for inside v for :
var app = new Vue({
el: '#app',
data: {
service: [{
title: 'blablabla',
price: '123',
benefits: ['a', 'b']
},
{
title: 'blaaablabla',
price: '12345',
benefits: ['aa', 'bb']
},
]
}
})
<script src="https://cdn.jsdelivr.net/npm/vue#2/dist/vue.js"></script>
<div id="app">
<div v-for="(item, i) in service" :key="i">
<p>{{item.title}}</p>
<p>My Benefits :</p>
<p v-for="(benefit, index) in item.benefits" :key="index">
{{benefit}}
</p>
</div>
</div>
You could flatten benefits and make it a computed property, then iterating through it would be much easier
var app = new Vue({
el: '#app',
data: {
service: [{
title: 'blablabla',
price: '123',
benefits: ['a', 'b']
},
{
title: 'blaaablabla',
price: '12345',
benefits: ['aa', 'bb']
},
]
},
computed: {
benefits: function() {
return this.service.flatMap(({
benefits
}) => benefits)
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue#2/dist/vue.js"></script>
<div id="app">
<div v-for="(benefit, i) in benefits" :key="i">
<p>{{benefit}}</p>
</div>
</div>

angularjs-dropdown-multiselect angularjs

I have a dropdown-multiselect. This directive uses Bootstrap's Dropdown with the power of AngularJS directives and binding. I new to angularjs.
<li id="bedsLists">
<div ng-dropdown-multiselect=""
options="beds"
selected-model="selectedBeds"
checkboxes="true"
events="{onItemSelect: onItemSelect, onItemDeselect: onItemDeselect}"
extra-settings="{showCheckAll: false, showUncheckAll: false, dynamicTitle: false, externalIdProp: 'Value', displayProp: 'Name', idProp: 'Value'}"
translation-texts="{buttonDefaultText: 'Beds'}">
</div>
</li>
From stateParams, required value is fetched, for example "1". How to make the first checkbox selected?
Try this
In your Controller
var myApp = angular.module('exampleApp',['angularjs-dropdown-multiselect']);
myApp.controller('appController', ['$scope', function($scope) {
$scope.selectedBeds = [{id: 1, label: "David"}]; // add the 1st data of your
$scope.beds = [
{id: 1, label: "David"},
{id: 2, label: "Jhon"},
{id: 3, label: "Lisa"},
{id: 4, label: "Nicole"},
{id: 5, label: "Danny"}];
}]);

Using two controllers within the same form, but code fails (angularjs)

Still new to AngularJS and I'm trying to combine two ng-controllers together.
Before I was trying to do this, the initial selected drop down option was correctly chosen. Right now as it stands, the drop down option I designed to be automatically selected is not selected initially.
The reason it's not, is because I am trying to play around with two ng-controllers. The old one works correctly if used by itself. This is the one for the initial drop down option to be correctly selected. Then, there is the second (and newer) ng-controller which is used to "print out" reviews. This controller basically pushes printed reviews onto the web page.
I tried adding that controller to the old one. I tried using that controller separately and add two ng-controllers in my form. I tried placing the drop down menu in a separate div and even an li afterwards and tried adding its own controller in there. So far... no luck.
Anything else I can try?
This is my plunker - it won't print out the text, though it does the rest:
http://embed.plnkr.co/tUTn4L02B57gV1V7psfk/preview
These are the specific parts:
HTML:
<blockquote ng-repeat="review in product.reviews">
<b>Stars: {{review.stars}}</b>
<br/>
{{review.body}}
<br/>
<cite>by: {{review.author}}</cite>
</blockquote>
<form name="reviewForm" ng-controller="ReviewController as reviewCtrl" ng-submit="reviewCtrl.addReview(product)">
<blockquote>
<b> Stars: {{reviewCtrl.review.stars}}</b>
<br/>
<b> Review: {{reviewCtrl.review.body}}</b>
<br/>
<cite>by: {{reviewCtrl.review.author}}</cite>
</blockquote>
<my-stars controller="starsController" model="reviewCtrl.review.stars" style="margin-bottom:50px;margin-left:36px;width:350px;"></my-stars>
JS:
app.controller('starsController', ['$scope', function($scope) {
$scope.review = {};
$scope.review.stars = '5 stars';
}])
app.directive('myStars', function() {
return {
restrict: 'E',
scope: { model: '=' },
template: '<select ng-model="model" ng-options="option.name as option.value group by option.type for option in options"></select>',
controller: function($scope) {
$scope.options = [
{ name: '1 star', value: '1 star', type:"Rate the product" },
{ name: '2 stars', value: '2 stars', type:"Rate the product" },
{ name: '3 stars', value: '3 stars', type:"Rate the product" },
{ name: '4 stars', value: '4 stars', type:"Rate the product" },
{ name: '5 stars', value: '5 stars', type:"Rate the product" }
];
}
};
/*
this.review = {};
this.addReview = function(product) {
product.reviews.push(this.review);
};
*/
});
app.controller("ReviewController", function() {
this.review = {};
this.addReview = function(product) {
product.reviews.push(this.review);
};
});
Firstly, as #WillIAM already wrote, it's as minimum strange to assign controller to directive's element whereas you already declared controller in directive itself.
Also, I don't see any code where you selecting current product for reviewing. If you want to have default 5 stars mark then create blank review with this property filled.
Fixed plunker
scope: { model: '=' },
By adding this line to the myStars directive you're giving it an isolated scope. This means that no data will be shared between the controller's scope and the directive's scope. If you want to pass in $scope.review.stars you'll need to pass it through the same way you passed in model
Giving your directive it's own controller like this:
<my-stars controller="starsController" model="reviewCtrl.review.stars" style="margin-bottom:50px;margin-left:36px;width:350px;"></my-stars>
Is kind of strange and defeats the purpose of the directive's controller. I would put everything that's in starsController into the directive's controller like so:
controller: function($scope) {
$scope.model = $scope.model || '5 stars'; //default to 5 stars
$scope.options = [
{ name: '1 star', value: '1 star', type:"Rate the product" },
{ name: '2 stars', value: '2 stars', type:"Rate the product" },
{ name: '3 stars', value: '3 stars', type:"Rate the product" },
{ name: '4 stars', value: '4 stars', type:"Rate the product" },
{ name: '5 stars', value: '5 stars', type:"Rate the product" }
];
}
That should fix your issue.

image not showing using iamgeurl?

This is my code
location: {
address: 'Google Headquarters',
city: 'Mountain View',
province: 'CA'
},
imageUrl: "img/angularjs-logo.png",
sessions: [
{
name: 'Directives Masterclass',
creatorName: 'Bob Smith',
duration: '1 hr',
level: 'Advanced',
abstract: 'In this sesison you will learn the ins and outs of directives!',
upVoteCount: 0
},
The image is not showing , this is the conroller.js, im using AngularJS v1.2.10.
<div ng-controller="EventController" style="padding-left:20px; padding-right:20px">
<img ng-src="{{event.imageUrl}}" alt="{{event.name}}" />
Maybe there is difference ways to show it , i dont get a error. I saw a toturial online and it does it the same way.
can anyone tell me what im doing wrong?
What you are supposed to have is the event variable in the scope of your controller to make it work:
Your controller:
app.controller('MainCtrl', function($scope) {
$scope.event = { location: {
address: 'Google Headquarters',
city: 'Mountain View',
province: 'CA'
},
title: "some title",
imageUrl: "http://plnkr.co/img/plunker.png",
sessions: [
{
name: 'Directives Masterclass',
creatorName: 'Bob Smith',
duration: '1 hr',
level: 'Advanced',
abstract: 'In this sesison you will learn the ins and outs of directives!',
upVoteCount: 0
},
]};
});
Your html:
<body ng-controller="MainCtrl">
<p><img ng-src="{{event.imageUrl}}" title="{{event.title}}" /></p>
</body>

How to pass list to angular array

I am a new to angular... I have an object list that I would like to pass to angular and use the ng-repeat function.
Using NameList that was passed from my controller, I would like to display a list of id-names-states. Before, I did the following...
<ul>
#foreach (var item in Model.NameList) {
<li>item.id - item.names - item.states</li> }
</ul>
the list would be something like...
id: '1', name: 'John Doe', city: 'Phoenix'
id: '2', name: 'Tony Hope', city: 'Queens'
id: '3', name: 'Jane Doe', city: 'Frederick'
id: '4', name: 'John Smith', city: 'Miami'
id: '5', name: 'Tom Ford', city: 'Atlanta'
After realizing angulars capabilities I would like to set up the list, with the ability to have the user filter based on names
So my question is, How do I pass the NameList object to get populated with angular, or can I just populate the object and tie the list to angular somehow?
This is what I have so far
<div id="angularWrapper" data-ng-app="" data-ng-controller ="SimpleController">
<div>Name:
<input type="text" data-ng-model="name" />
</div>
#*I would like to pass Model.NameList to customers*#
<div data-ng-model="#Model.NameList"></div>
<br />
<ul>
<li data-ng-repeat="cust in customers | filter:name">{{cust.id + - + cust.name + - + cust.state}}</li>
</ul>
</div>
In your controller:
$scope.customers = [
{ id: '1', name: 'John Doe', city: 'Phoenix' },
{ id: '2', name: 'Tony Hope', city: 'Queens' },
{ id: '3', name: 'Jane Doe', city: 'Frederick' },
{ id: '4', name: 'John Smith', city: 'Miami' },
{ id: '5', name: 'Tom Ford', city: 'Atlanta' }
];
I think you're confused about how AngularJS binding works, you should read the guide on Data Binding: http://docs.angularjs.org/guide/databinding
In the meantime here's a simple JSFiddle I think does what you're looking for: http://jsfiddle.net/mikeeconroy/75WPW/1/
<div ng-controller="myCtrl">
Name: <input type="text" ng-model="name" />
<ul>
<li ng-repeat="cust in customers | filter:name">{{cust.id}} - {{cust.name}} - {{cust.city}}</li>
</ul>
</div>
And the controller:
angular.module('myApp',[])
.controller('myCtrl', ['$scope','mySrv',function ($scope,mySrv) {
$scope.name = '';
$scope.customers = [];
$scope.customers = mySrv.getCustomers();
}])
// fake service, substitute with your server call ($http)
.factory('mySrv',function(){
var customers = [
{id: '1', name: 'John Doe', city: 'Phoenix'},
{id: '2', name: 'Tony Hope', city: 'Queens'},
{id: '3', name: 'Jane Doe', city: 'Frederick'},
{id: '4', name: 'John Smith', city: 'Miami'},
{id: '5', name: 'Tom Ford', city: 'Atlanta'}
];
return {
getCustomers : function(){
return customers;
}
};
});
You could also set $scope.customers by using the resolve function of your route.
I came up with a solution that may have a possible alternative...
<div id="angularWrapper" data-ng-app="demoApp" data-ng-controller="SimpleController">
<div>
Name:
<input type="text" data-ng-model="name" />
</div>
<div>
<ul>
<li data-ng-repeat="eg in List | filter: name">{{ eg.Name }}</li>
</ul>
</div>
<br />
<script>
$(function () {
var scope = angular.element('#angularWrapper').scope();
#foreach (var npo in Model.NameList)
{
#: scope.AddList({ Name: '#eg.Name' });
}
scope.$apply();
});
</script>
</div>
.js file
function getList() {
var self = this;
self.Name = "";
}
var demoApp = angular.module('demoApp', []);
demoApp.controller('SimpleController', SimpleController); //could just load the function($scope) from simplecontroller..
function SimpleController($scope) {
$scope.List = [];
$scope.AddList = function (data) {
var eg = new getList();
eg.Name = data.Name;
$scope.List.push(eg);
}
}

Resources