0

I need some help as I cannot make Angular to call correctly an API inside Visual Studio 2017. Here is part of my code(I have imported and injected everything Angular needs as to work):

@Injectable()
export class GetCustomerInfoService {

    constructor(private http: HttpClient) { }

    getResults() {
        return this.http.get('http://localhost:65040/api/employees');
    }
}


@Component({
    selector: 'apply',
    templateUrl: './apply.component.html',
    providers: [GetCustomerInfoService]
})
export class ApplyComponent {

    constructor(private customerInfo: GetCustomerInfoService) {
        this.customerInfo.getResults().subscribe(result => {
            console.log(result);
        });

    }

Inside Startup.cs:

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
    routes.MapSpaFallbackRoute(
        name: "spa-fallback",
        defaults: new { controller = "Home", action = "Index" });
});

and test.cs Controller:

namespace Coc.Controllers
{
    public class TestController : Controller
    {
        [HttpGet("api/employees")]
        public JsonResult GetEmployees()
        {
            return new JsonResult(new List<object>()
            {
                new {employeeid = 01989, Name = "John Patrick"},
                new {employeeid = 01987, Name= "Michael"},
                new {employeeid = 01988, Name= "Akhil Mittal"}
            });
        }
    }
}

By using postman http://localhost:65040/api/employees I am getting the data from TestController. What do I need as to get the data from Angular GetCustomerInfoService as well? Now I am getting the following error:

An unhandled exception occurred while processing the request. NodeInvocationException: Uncaught (in promise): ReferenceError: XMLHttpRequest is not defined ReferenceError: XMLHttpRequest is not defined

comodor16
  • 17
  • 4
Unknown developer
  • 5,414
  • 13
  • 52
  • 100

2 Answers2

2

Your route is just plain wrong. You define route for

routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{action=Index}/{id?}");

and register test/api/employees, but you call /api/employees.

public class TestController : Controller
{
    // This route is relative to the /test path, because that's the name of the controller
    [HttpGet("api/employees")]
    public JsonResult GetEmployees() { ... }
}

Since the routing middleware finds no controller called "api", it will fall back to the SpaServices fallback route, which loads the angular application.

You probably want make something like this

[Route("api/employees")]
public class TestController : Controller
{
    [HttpGet]
    public JsonResult GetEmployees() { ... }

    // or this, but not recommended, to to harder maintenance. Notice the slash in front of the route
    [HttpGet("/api/employees")]
    public JsonResult GetEmployees() { ... }
}

Or you define a standard route for all api controllers:

routes.MapRoute(
    name: "defaultApi",
    template: "api/{controller}/{id?}");

Now this should be sufficient

public class TestController : Controller
{
    // Just the verb
    [HttpGet]
    public JsonResult GetEmployees() { ... }
}

But the later one may conflict with your HomeController, as it will treat all controllers as "Api" controllers (read: even /api/home would route to HomeController).

Tseng
  • 61,549
  • 15
  • 193
  • 205
  • Thank you for your answer. I tried your suggestions but I am still getting the error... For example I changed the test Controller to `[Route("api/employees")] public class TestController : Controller { [HttpGet] public JsonResult GetEmployees() { ... } }` Why it does not still run? – Unknown developer Nov 11 '17 at 23:48
  • I've just discovered something very weird. If putting a breakpoint at ` return this.http.get('http://localhost:65040/api/employees');` I am getting the right results. If not I am getting the error... – Unknown developer Nov 12 '17 at 00:21
  • Hard to say, could be server-sided rendering doesn't support http/ajax requests. See my answer [here](https://stackoverflow.com/a/47023279/455493) – Tseng Nov 12 '17 at 00:34
1

Your error suggests that your application is being run on Node. This might occur for example if you have server-side pre-rendering, as is the case with the Angular template that comes with Visual Studio.

However, XMLHttpRequest is only available in the browser. According to this question, you need to install support for XMLHttpRequest on Node. Alternatively, you could try disabling server-side pre-rendering so that your Angular code is only run in the browser.

I believe it is HttpClient that needs XMLHttpRequest. Therefore you could also try the older Http instead of HttpClient.

pere57
  • 652
  • 9
  • 18
  • Please, see my comments made for @Tseng – Unknown developer Nov 12 '17 at 00:22
  • So are you using server-side pre-rendering? Did you generate your project using the Angular CLI or the VS template? – pere57 Nov 12 '17 at 00:24
  • I am using server-side pre-rendering. I generated my project using VS 2017. What is the best solution according to your opinion? – Unknown developer Nov 12 '17 at 00:27
  • I have disabled server-side pre-rendering and it works!!! What am I losing with this choice? – Unknown developer Nov 12 '17 at 00:31
  • @Unknowndeveloper: Not much. Faster loading on first request (user do not have to wait until dependencies are loaded before angular app is rendered), indexing by google/webcrawlers (javascript/angular apps are hard to index because their content is dynamically generated by javascript, though there have been improvements in the past years). And as in the answer linked in my command you can also made code conditional so client calls won't be run when rendered on server) – Tseng Nov 12 '17 at 00:37
  • The weird thing is, I created a new Angular project in VS2017. I ran `npm update` (updates angular v4.2.5 to v4.4.6) then added the parts of the code shown by the OP (plus the imports etc. to make it work). I didn't get any errors and the browser console correctly showed the 3 employees. @Unknowndeveloper what version of angular shows in your package.json? – pere57 Nov 12 '17 at 00:57
  • Actually 4.4.6 ! – Unknown developer Nov 12 '17 at 01:06