Home > OS >  Data from Microsoft SQL Server sent to .NET Web API correctly, but not showing up in Angular
Data from Microsoft SQL Server sent to .NET Web API correctly, but not showing up in Angular

Time:12-31

My database table looks like this - sample data:

enter image description here

Table structure:

enter image description here

I am trying to get all the rows to show up on the console of chrome devtools for now.

The .NET Web API is shown below; it is working fine I checked in Postman. This is the Entity Framework API controller:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;
using System.Web.Http.Description;
using template;

namespace template.Controllers
{
    [EnableCors(origins: "*", headers: "*", methods: "*")]

    public class templatesController : ApiController
    {
        private editorEntities db = new editorEntities();

        // GET: api/templates
        public IQueryable<template> Gettemplates()
        {
            return db.templates;
        }

        // GET: api/templates/5
        [ResponseType(typeof(template))]
        public IHttpActionResult Gettemplate(int id)
        {
            template template = db.templates.Find(id);

            if (template == null)
            {
                return NotFound();
            }

            return Ok(template);
        }

        // PUT: api/templates/5
        [ResponseType(typeof(void))]
        public IHttpActionResult Puttemplate(int id, template  template)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            if (id != template.tempID)
            {
                return BadRequest();
            }

            db.Entry(template).State = EntityState.Modified;

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!templateExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return StatusCode(HttpStatusCode.NoContent);
        }

        // POST: api/templates
        [ResponseType(typeof(template))]
        public IHttpActionResult Posttemplate(template template)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            db.templates.Add(template);

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateException)
            {
                if (templateExists(template.tempID))
                {
                     return Conflict();
                }
                else
                {
                     throw;
                }
            }

            return CreatedAtRoute("DefaultApi", new { id = template.tempID }, template);
        }

        // DELETE: api/templates/5
        [ResponseType(typeof(template))]
        public IHttpActionResult Deletetemplate(int id)
        {
            template template = db.templates.Find(id);

            if (template == null)
            {
                return NotFound();
            }

            db.templates.Remove(template);
            db.SaveChanges();

            return Ok(template);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }

            base.Dispose(disposing);
        }

        private bool templateExists(int id)
        {
            return db.templates.Count(e => e.tempID == id) > 0;
        }
    }
}

Here's the working Web API call:

enter image description here

Here is the .html where when the button is pressed, the getthem() function is called.

<button (click)="getThem()"></button>
<!-- <mat-form-field appearance="fill">
    <mat-label>Chose Template</mat-label>
    <mat-select>
      <mat-option *ngFor="let temp of Templates" [value]="temp.value">
        {{temp.viewValue}}
      </mat-option>
    </mat-select>
  </mat-form-field> -->

  <div >
    <div >
        <button>
          <mat-icon>add</mat-icon>
        </button>
        <button >Save Current Template</button>
    </div>  
</div>

This is the .ts file in Angular for the class template that holds these 4 attributes

export interface template {
    templateID: number,
    templateName: string,
    content: string,
    version: number,
}

This is the service that holds the api call:

export class TemplatesService {

  constructor(
    private http:HttpClient,
  ) { }

  getTemplates(): Observable<template[]>{
    return this.http.get<template[]>('https://localhost:44334/api/templates');
  }
}

This is the .ts file for the Angular component that is to render the data . For now I just want to see they are reaching so they are just displaying on the console.

@Component({
  selector: 'app-template',
  templateUrl: './template.component.html',
  styleUrls: ['./template.component.css']
})
export class TemplateComponent implements OnInit {

  templates: template[]=[];
constructor(
  private templateService: TemplatesService
){}
  ngOnInit(): void {
  }
  getThem(): void {
    
    this.templateService.getTemplates()
      .subscribe(templates=>this.templates=templates);
console.log(this.templates);

  }
}

This is a screenshot of the data not showing up in devtools sources tab and in console

enter image description here

enter image description here

network tab

enter image description here

CodePudding user response:

Well, there are possibly other problems, but right off the bat I see a problem with your asynchronous code. Here is your current code annotated with notes as to why it's not behaving as you expected it to:

// TODO: rename getThem. This is the most generic name to the
// point that it might as well be called x(). What about something
// like refreshTemplates()? Or getTemplates()?
getThem(): void {
    // getTemplates() is asynchronous, which means it doesn't block
    // further execution in this function...
    this.templateService.getTemplates()
      .subscribe(templates=>this.templates=templates);
    // ... which means this will always be its' initial value because 
    // getTemplates hasn't completed yet. We need to wait for subscribe 
    // to emit a value.
    console.log(this.templates);
}

So, first suggestion is refactor your code to wait for your observable to emit a function before you console.log your property. You can do this simply by putting your console.log inside your callback function

getThem(): void {
    // Retrieve templates and do stuff with emitted value
    this.templateService.getTemplates().subscribe(templates=> { 
        this.templates = templates;
        // Since we are calling this from inside our callback function, 
        // this.templates will be whatever our getTemplates() function 
        // emitted after we subscribed to it.
        console.log(this.templates)'
    });
}

The next problem is that your network tab showed pending. Did those ever complete? There could be something else going on there.

  • Related