Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 810
  • Last Modified:

MVC4 Web API Service & MVC4 AngularJS Get?

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
WorknHardr
Asked:
WorknHardr
  • 7
  • 6
1 Solution
 
käµfm³d 👽Commented:
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
 
jayakrishnabhCommented:
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
 
WorknHardrAuthor Commented:
So far I run debug in Firefox / IE using F12 and no error. AngularJS is new to me and so is debugging it.
0
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.

 
käµfm³d 👽Commented:
...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
 
WorknHardrAuthor Commented:
I'm also concerned that the Web Api service returns XML and I don't know if AngularJS expects JSON or XML?
0
 
käµfm³d 👽Commented:
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
 
WorknHardrAuthor Commented:
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
 
käµfm³d 👽Commented:
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
 
WorknHardrAuthor Commented:
Any success?
0
 
käµfm³d 👽Commented:
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
 
WorknHardrAuthor Commented:
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
 
käµfm³d 👽Commented:
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
 
WorknHardrAuthor Commented:
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
 
WorknHardrAuthor Commented:
Thx again...
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

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.

  • 7
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now