ASP.NET Webforms and AngularJS - angularjs

I'm still struggling to get my first ASP.NET WebApi / AngularJS app up and running...
I'm trying to query a WebAPI service (which I've written and verified using Fiddler that it works just fine) from Angular, and I'm trying to show the data returned on my ASP.NET Webforms page. I studied a great many tutorials and Pluralsight courses, and really thought I knew how to do it - but Angular doesn't agree with me :-(
I have my Angular app/controller here:
var app = angular.module('MyApp', []);
app.controller('MyCtrl', function ($scope, $http) {
$scope.model = [];
//Call to web API
var Url = 'http://localhost:13811/api/v1/mydata';
$http({
method: 'GET',
url: Url
}).success(function (MyList) {
$scope.model = MyList;
}).error(function () {
});
});
My (very limited) JS/Angular understanding is that this defines an Angular app and a controller, and that if I add this controller to a DOM element on my ASPX page, the controller will be invoked, will make that call out to my WebAPI service (and I do see that this is happening), and then stores the results (a list of some data objects from the database) into the $scope.model variable.
So I was assuming that I would be able to integrate this into a blank ASPX something like this:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="DemoAngular.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Angular Demo</title>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/app/plz-controller.js"></script>
</head>
<body ng-app="MyApp">
<form id="form1" runat="server">
<div ng-controller="MyCtrl">
<span>Angular says: {{1+2}} </span>
<div class="list-group" data-ng-repeat="x in model">
<div class="list-group-item">
<span>{{x.Field1}}</span><br/>
<span>{{x.Field2}}</span><br/>
</div>
</div>
</div>
</form>
</body>
</html>
I was assuming that adding the ng-app="MyApp" directive to the <body> tag would link the ASPX page to the Angular app, and adding the ng-controller="MyCtrl" to that <div> would then instantiate the Angular controller (and thus make the WebAPI call - this it does, I see that in the F12 developer tools).
I was also expecting that by using the data-ng-repeat="x in model" directive, I would be able to iterate over the list of data elements returned from the WebAPI call, and using the {{....}} syntax, I was hoping to be able to access the individual fields of those objects and display them.
ALAS: I do see Angular says: 3 at the top of my page, so Angular appears to be "there" and active, and I do see the WebAPI call in the F12 developer tools (and I can verify that the expected number of data elements is being returned) - yet no matter what I try, I cannot find any way to actually SHOW that data having been retrieved from WebAPI on my ASPX page......
Any ideas? What am I missing? Must be something really stupid - I'm sure - but I just don't see the forest for the trees anymore........

Fire up the debugger and put a breakpoint on the $scope.model = MyList line. Chances are that you're getting an http response object back here and you need to change it to something like $scope.model = MyList.data. Examining the object in the debugger will tell you for sure if this is the case.

Related

Angular Dropdown (could be just IE): strange positioning of dropdown in IE

I'm taking baby steps with Angular and writing simple stuff and testing across browsers, I have a simple script to bind a menu against a JSON string array. I want to do the whole Angular MVC instead of Javascript DOM manipulation.
In my tests I can see a strange behaviour as to the positioning of the top of the menu in IE dependent upon which item is selected. Anyone know how to fix this? I would like to use an Angular friendly solution, like Bootstrap?
Menu looks good in Firefox and Chrome.
<html ng-app="myNoteApp">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<body>
<div ng-controller="myCarSelector">
<h2>Menu</h2>
<p>Make of car : <span ng-bind="selectedCarMake"></span></p>
<select ng-model="selectedCarMake" ng-options="val for val in carmakes"></select>
</div>
<script>
// was in separate file but pasted in for demo purposes
var app = angular.module("myNoteApp", []);
</script>
<script>
// was in separate file but pasted in for demo purposes
app.controller("myCarSelector", function ($scope) {
$scope.selectedCarMake = "BMW"; // default value
$scope.carmakes = ["Audi", "BMW", "Volkswagen"];
});
</script>
</body>
</html>
I like to accept answers and then move on to next question.
Here is a screen grab of the problem in IE 11
It seems browser default behaviour.

Sharepoint 2013 won't work with Angularjs

I tried to run this very simple input test on my SharePoint 2013 site. It worked well at first but after some other experimenting within same page in different content editors (I did not touch the input test) it broke and now shows only the search with double brackets. I have tried implementing this in Content editor and script editor but nothing seems to work. It only shows text and {{search}}
<script src=".../SiteAssets/javascript/angular.min.js"></script>
<script src=".../SiteAssets/javascript/jquery-2.1.4.min.js"></script>
<div>
<input type="text" ng-model="search">
<p>you're searching for: {{search}}</p>
</div>
Also I can't figgure out why the simples Hello World won't show as it should. It also shows the double brackets.
var app = new angular.module("mainApp", []);
app.controller("HelloController", function ($scope) {
$scope.greeting = 'hello';
});
angular.bootstrap(document, ['mainApp']);
Above is controller and below is the .html.
<script type="text/javascript" src=".../SiteAssets/javascript/angular.min.js"></script>
<script type="text/javascript" src=".../SiteAssets/javascript/HelloController.js"></script>
<div ng-app='mainApp' ng-controller='HelloController'>
<p>{{greeting}}, World</p>
</div>
I have tested the Minimal download strategy features effect on these problems but it does not make any difference.
I hope someone can help!
BR,
Noora
You need to bootstrap you angular app on angular.element ready after DOM is loaded properly.
Code
angular.element(document).ready(function() {
angular.bootstrap(document, ['mainApp']);
});
You should call angular.bootstrap() after you've loaded or defined
your modules. You cannot add controllers, services, directives, etc
after an application bootstraps.
Doc Link

how to create reusable component in angularJS?

I have two controllers at the moment, one is a form where a user inputs a value and the other is a graph that renders based on an api search. I would need to refresh or re run the second controller based on the input from the first. I am almost certain this is bad design on my part but have not found the ideal way to do it.
HTML code:
<html>
<body>
<!-- this is the graph generator-->
<div ng-controller="GraphAppCtrl"></div>
<!-- this is th form submittal section-->
<div ng-controller="FormCtrl" id="FormCtrl">
<form novalidate class="simple-form">
Name: <input type="text" ng-model="tech"/><br />
<button ng-click="submit(tech)">Submit</button>
</form>
</div>
</body>
</html>
Angular Code:
var app = angular.module('testApp', []);
app.controller('FormCtrl', function ($scope) {
$scope.submit = function(tech){
// Need to be able to call the function that generates graph and pass it the tech value
}
}
app.controller('GraphAppCtrl', function ($scope) {
//here I do a bunch of stuff to generate graph, like http request from third party api etc.
}
What is happening now since I have a reference to the graph controller in the my index.html page it renders the first time based on default parameters, but I would need it to render based on the submit.
I have looked Directives and experimented with the answer in this question but it seems as Directives more of a solution to pass data between controllers rather than what I am trying to do.
You should create an Angular Service
https://docs.angularjs.org/guide/services

Angular Demo app

I've been learning Angular and hit a strange wall . . . first off I ran an angular demo using DEPLOYD and SERVER.JS and everything ran fine. I also ran another that hits a RESTful web service online, and it ran fine. So I take what seems to be the next logical step and create my own RESTful web service and it deploys to TOMCAT just fine. I can query the service in my browser to localhost, and it runs fine. So far so good.
So, I build a very simple Angular app to hit that service and nothing gets returned. OK, I figure I messed something up . . . so I mod my demo app to hit a DEPLOYD instance, and it works. I mod it to his the existing service, and it works . . . but when I point it to my own RESTful service nothing gets returned. I can't afford to lose any more hair over this. Here are some particulars:
When tested in the browser, my service is returning:
[{"person":{"id":1,"fullName":"Alpha","age":10}},{"person":{"id":2,"fullName":"Bravo","age":20}},{"person":{"id":3,"fullName":"Charlie","age":30}},{"person":{"id":4,"fullName":"Delta","age":40}},{"person":{"id":5,"fullName":"Echo","age":50}},{"person":{"id":6,"fullName":"Foxtrot","age":60}}]
A pretty simple JSON array, right?
Here is my HTML:
<!doctype html>
<html ng-app>
<head>
<title>Hello AngularJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8 /angular.min.js"></script>
<script src="hello.js"></script>
<link href="css/bootstrap.css" rel="stylesheet" />
<link href="css/bootstrap-theme.css" rel="stylesheet" />
</head>
<body>
<div ng-controller="Hello">
<div class="well" ng-repeat="person in data.person">
<h3>
<strong>{{person.id}}</strong>
<span class="pull-right label label-primary">
{{person.age}}
</span>
</h3>
</div>
</div>
</body>
</html>
And here is my controller javascript:
function Hello($scope, $http) {
$scope.data = {};
$http.get("http://localhost:8085/TestWS/service/getAllPersonsInJSON").
success(function(data) {
$scope.data.person = data;
});
#scope.data.person();
}
I pared it down to the essentials, I think . . . but no joy getting data displayed. Anyone care to help me avoid making a larger bald spot?
TIA,
Ted
I was able to run this on my machine.
The issue looks like with nesting of data to an extra step.
The data you are receiving is a json array, to display this I directly assigned it to person.
Made these changes to controller :
removed $scope.data = {};
So controller had the below 3 lines.
$http.get("url").
success(function(data) {
$scope.person = data;
});
Then accessed the data in HTML file :
<div ng-controller="Hello">
<div class="well" ng-repeat="person in person">
<h3>
person is
<strong>{{person.person.id}}</strong>
<span class="pull-right label label-primary">
{{person.person.age}}
</span>
</h3>
</div>
</div>
Hope it will help.
Cheers
Remove this line as that's not really valid Angular code and person isn't a function.
#scope.data.person();
Everything else looks great.
Try this:
$scope.data.person = data.data;
This is because, the $http.Get(function(data){},..) will return http response packet in data variable. In order to access the data inside http response packet, you've to access data.data object.
Edit:
If above workaround donot works, use console.log(data) inside success callback and have a look at browser's console to inspect what data is being actually passed on by the success callback function.
Hope this helps.

angularjs specific page without ng-incude

I design my pages with angularjs like following
<html>
<head></head>
<body>
<ng-view></ng-view>
<ng-include="'footer-tpl.html'">
</body>
</html>
so whenever navigate to any pages will just change the ng-view, but now I want to have a
page without the <ng-include="'footer-tpl.html'">. How to do that?
I just realized you can use ngHide with ngInclude:
http://plnkr.co/edit/BBpfQBRgtr7tAK6iFRTR?p=preview
HTML
<div ng-include="'footer.html'" ng-hide="hideFooter"></div>
JavaScript
angular.module('test', []).controller('test', function ($scope) {
// TODO set this to true to hide the footer, if you don't set it, it stays visible
//$scope.hideFooter = true;
});
When this patch for ngIf makes it into a release, you can use it in place of ngHide. It seems like it'll prevent footer.html from even being loaded if you hit the right view, but I'm not totally sure on that.

Resources