-2

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 class="example-button-row">
    <div class="example-flex-container">
        <button>
          <mat-icon>add</mat-icon>
        </button>
        <button class="save">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

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Devi Suresh
  • 129
  • 1
  • 10
  • `getThem()` is never called… – smithnblack Dec 30 '21 at 17:44
  • sorry, i forgot to add the call ..its in the html page on a button click. its added now – Devi Suresh Dec 30 '21 at 17:46
  • `Templates` (in the HTML) != `templates` (in the typescript). – R. Richards Dec 30 '21 at 17:52
  • its commented out..havent gotten there yet..still working on it to get displayed in the console in the .ts file. – Devi Suresh Dec 30 '21 at 17:53
  • 1
    Can you put a logger and see if it prints the data. `.subscribe(templates=> {console.log(templates); this.templates=templates;})` The http call is an async operation, so debugger will reach the end of `getThem()` before the http call is over. Logger will help. – Siddhant Dec 30 '21 at 17:53
  • Show the network tab? – MikeOne Dec 30 '21 at 17:56
  • @Siddhant i had done that previously, forgot to include it after i was trying different things. ive updated it. – Devi Suresh Dec 30 '21 at 17:59
  • @DeviSuresh The console should be within the arrow function body, as mentioned in my previous comment. Also you can check the response in network call. – Siddhant Dec 30 '21 at 18:01
  • @Siddhant ok that worked and it printed in console.. – Devi Suresh Dec 30 '21 at 18:05
  • but when i do this ----> this.templateService.getTemplates() .subscribe(templates=> {console.log(templates); this.templates=templates;}) console.log(this.templates); this second console. log still prints empty array – Devi Suresh Dec 30 '21 at 18:07
  • 1
    Please try this -> `this.templateService.getTemplates().subscribe(templates=> { this.templates=templates; console.log(this.templates);})` – Siddhant Dec 30 '21 at 18:11
  • 2
    That is normal. See this: https://stackoverflow.com/questions/43055706/how-do-i-return-the-response-from-an-observable-http-async-call-in-angular – R. Richards Dec 30 '21 at 18:11
  • @Siddhant got it..so now i can use this.templates in my html to display each tuple? – Devi Suresh Dec 30 '21 at 18:15
  • @Siddhant i understand the concept now, the data is there but console.log runs before the http call so it wont print it.... this.templates now has the data . Thank you so much – Devi Suresh Dec 30 '21 at 18:20

1 Answers1

0

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.

Dean
  • 2,084
  • 17
  • 23