Expiring Today—Celebrate National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

MVC4 Web API Service &  MVC4 AngularJS Get?

Posted on 2014-04-08
14
Medium Priority
?
768 Views
Last Modified: 2014-04-16
Just now breaking into AngularJS and MVC4. I have a working test service on our local 2012 server which returns xml in a dev browser like so:
192.168.1.11:8080/api/values

<ArrayOfPerson>
   <Person>
      <ID>1</ID>
      <Name>sankar</Name>
      <Address>cuttack</Address>
      <DOB>1983-01-22T00:00:00</DOB>      
   </Person>
   <Person>
      <ID>3</ID>
      <Name>My Test Name</Name>
      <Address>My Test Address</Address>
      <DOB>1980-01-01T00:00:00</DOB>     
   </Person>
</ArrayOfPerson>

Open in new window

I have a dev running VS2012 and MVC4 project with the following code. I'm trying to return a list of Persons. Instead it never errors or returns any data.

Q. What am I doing incorrectly?

public class ValuesController : ApiController
    {
        PersonEntities db = new PersonEntities();
        
        public IEnumerable<Person> Get()
        {
            return db.Persons.ToList();
        }
}

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<div ng-controller="GetPeople">
    <table>
        <tr ng-repeat="person in persons">
            <td>{{person.Id}}</td>
        </tr>
    </table>    
</div>

<script src="~/Scripts/angular.min.js"></script>
<script type="text/javascript">

    function GetPeople($scope, $http) 
    {
        $http.get('192.168.1.11:8080/api/values').
            success(function (data) 
            {
                $scope.values = data;
            });
    }
</script>

Open in new window

0
Comment
Question by:WorknHardr
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 6
14 Comments
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 39987615
How do you know it's not erroring? I don't see where you have attached a handler to the error callback. Have you tried running a utility like Fiddler to see data going over the wire?
0
 
LVL 5

Expert Comment

by:jayakrishnabh
ID: 39988465
Is the webservice a ScriptService and the method a ScriptMethod for it to be accessed from javascript.
Also, as kaufmed suggested, please try using error handler to check whether if it is errored while calling the script method.
0
 

Author Comment

by:WorknHardr
ID: 39988484
So far I run debug in Firefox / IE using F12 and no error. AngularJS is new to me and so is debugging it.
0
Understanding Linux Permissions

Linux for beginners: How to view the permissions associated with files and directories and also how you can change them.

 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 39988487
...and no error.
OK, but again have you attached to the error callback? There is a difference between a Javascript error and an error (code) being returned from a web service. The former causes your script to stop working, and it's what shows up in a debugger; the latter is normal operation, and it won't stop your script from running.
0
 

Author Comment

by:WorknHardr
ID: 39988492
I'm also concerned that the Web Api service returns XML and I don't know if AngularJS expects JSON or XML?
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 39988497
I'm also concerned that the Web Api service returns XML...
Well, lucky for you Web API returns either XML or JSON right out of the box. (This assumes that you are not returning string from your service call, and passing XML that you yourself serialized.) Read up on content negotiation.

If you are serializing the XML yourself, then content negotiation is out the window. Still, I don't see why Angular won't accept XML. Data is data.
0
 

Author Comment

by:WorknHardr
ID: 39989646
The Web API service is now returning JSON instead of XML like so by simply typing this url in a browser window: 192.168.1.11:8080/api/values
[{"ID":1,"Name":"sankar","Address":"cuttack","DOB":"1983-01-22T00:00:00"},{"ID":3,"Name":"My Test Name","Address":"My Test Address","DOB":"1980-01-01T00:00:00"}]

Open in new window

Note: I also downloaded 'Fiddler' and the data string above returns in it as well.

As a JSON test I'm using the AJAX code below, it too never returns any data and the error alert never opens.
Note: I've never had this much trouble returning data to a web page using MVC Action Results and Views. It seems like returning JSON would be much easier than this. As you said before, "it's just data", I say it's like pulling teeth...
<div>
    <table id="tbPerson"></table>
</div>

<script src="~/Scripts/jquery-2.1.0.min.js"></script>
<script type="text/javascript">
    $(document).ready(function () 
{
$.ajax({
            url: '192.168.1.11:8080/api/values',
            type: 'GET',
            dataType: "json",
            contentType: 'application/json; charset=utf-8',
            success: function (data)
            {
                for (var i = 0; i < data.length; i++)
                {
                    $("<tr> <td>" + data[i].Name + "</td> </tr>").appendTo("#tbPerson");                   
                }
            },
            error: function (xhr, status, error)
            {              
                    alert(error);
            }
        });
});
</script>

Open in new window

0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 39989677
I haven't yet played with Angular, but I'm always up for a challenge. I'll take a look at it tonight when I get home from work, and I'll see if I can work up an example for you.
0
 

Author Comment

by:WorknHardr
ID: 39998598
Any success?
0
 
LVL 75

Accepted Solution

by:
käµfm³d   👽 earned 2000 total points
ID: 40000648
Sorry, I looked at it, but I started running into cross-origin errors, so I had to work that out.

Keep in mind that I've only started looking at Angular, but what mainly jumps out at me is that you don't have the ng-app directive anywhere. For example:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
    @Scripts.Render("~/bundles/angular")
</head>
<body ng-app>
    @RenderBody()

    @Scripts.Render("~/bundles/jquery")
    @RenderSection("scripts", required: false)
</body>
</html>

Open in new window


Notice how I've added it to the <body> tag. So now when all of my HTML is rendered:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
    <link href="/Content/site.css" rel="stylesheet"/>
    <script src="/Scripts/modernizr-2.6.2.js"></script>
    <script src="/Scripts/angular.js"></script>
</head>
<body ng-app>
<h2>Index</h2>
<div ng-controller="GetPeople">
    <table>
        <tr ng-repeat="person in values">
            <td>{{person.Id}}</td>
        </tr>
    </table>    
</div>
<script type="text/javascript">
    function GetPeople($scope, $http) {
        $http.get('http://localhost:60455/api/values').
            success(function (data) {
                $scope.values = data;
            });
    }
</script>
    <script src="/Scripts/jquery-1.8.2.js"></script>    
</body>
</html>

Open in new window


The other issue I see is that you called the property values when you assigned it to the $scope, but you referred to it as people in your ng-repeat. Pick one or the other. (I went with values above.)

using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace MvcApplication1.Controllers
{
    public class ValuesController : ApiController
    {
        PersonEntities db = new PersonEntities();

        public IEnumerable<Person> Get()
        {
            return db.Persons.ToList();
        }
    }

    public class PersonEntities
    {
        public PersonEntities()
        {
            this.Persons = new List<Person>()
            {
                new Person() { Id = 1 },
                new Person() { Id = 2 },
                new Person() { Id = 3 },
            };
        }

        public IEnumerable<Person> Persons { get; set; }
    }

    public class Person
    {
        public int Id { get; set; }
    }
}

Open in new window


Screenshot
0
 

Author Comment

by:WorknHardr
ID: 40002573
Excellent! It's working! Yea!

Q. To be clear,  the $scope.values must match the controller name 'Values'

It's been a mystery to me where other Internet examples get the scope sub-name...
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 40002606
Q. To be clear,  the $scope.values must match the controller name 'Values'
No. It must match what you have in your ng-repeat. Think of ng-repeat as a C# foreach loop, where you have the form:

foreach (var variable in collection)

Open in new window


In $scope.XXXX, "XXXX" must be collection.

i.e.

$scope.collection

Open in new window


For the moment, ignore my code and focus on your original code. the $scope line would need to be:

$scope.people = data;

Open in new window

0
 

Author Comment

by:WorknHardr
ID: 40002614
Yea, I see that now. I kept thinking it must be hard-typed somewhere else to show in intellisense.

Thanks, you are good teacher...
0
 

Author Closing Comment

by:WorknHardr
ID: 40002626
Thx again...
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction Knockoutjs (Knockout) is a JavaScript framework (Model View ViewModel or MVVM framework).   The main ideology behind Knockout is to control from JavaScript how a page looks whilst creating an engaging user experience in the least …
A while back, I ran into a situation where I was trying to use the calculated columns feature in SharePoint 2013 to do some simple math using values in two lists. Between certain data types not being accessible, and also with trying to make a one to…
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

719 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question