0

UPDATE: my html template:

 <input type="text" (keyup)="onNameKeyUp($event)">
 <button (click)="getOneWord()">Get Profile</button>
 <span>{{translation}}</span>

ts. component:

onNameKeyUp(event: any){
this.spelling= event.target.value;    

I am getting desperate here, so hopefully someone will get me unstuck! I managed to send a get request from an angular service to an express server. The server responds with the data. My problem is that I cannot display the data returned by the server in an angular component.

this is my web-service:

  getWord(name: string): Observable<Word> {
  return this.http.get<Word>('http://localhost:3000/api/words/' + name);
 }

Then I am injecting this service in a component, calling it:

getOneWord(){
this.webService.getWord(this.spelling)
.subscribe(res =>
 console.log(res));

However, either the whole data is displayed or none of it. What I want is that if the user searches/enters 'aman', only the first object will be returned.

the data is:

var words=[
{spelling: "aman", category: "noun", translation: "water"},
{spelling: "azzel", category: "verb", translation: "run"},
{spelling: "aberkan", category: "adjective", translation: "black"},
{spelling: "gar", category: "preposition", translation: "between"}];

2 Answers 2

1

Starting point

Part A

getWord(name: string):      Observable<Word> { return this.http.get<Word>('http://localhost:3000/api/words/' + name); }
  1. your API is supposed to return item that matches the word but instead you are getting the whole word back. there seems to be a bug on that end
  2. you need to update your service to expect an array of word rather than a single word

Update this

getWord(name: string): Observable<Word[]> { return this.http.get<Word[]>('http://localhost:3000/api/words/' + name); }

Part B

if you are still getting an array of word back.

1) declare a global variable

theWord;

2)

getOneWord(){ this.webService.getWord(this.spelling) .subscribe((res: Word[]) => { this.theWord = res.find(d => d.spelling === this.spelling )}  );

if your API has been fixed

you should probably be getting the word back.

  getOneWord(){ this.webService.getWord(this.spelling) .subscribe(res => console.log(res));
Sign up to request clarification or add additional context in comments.

7 Comments

I don't know what I'm doing wrong. It's returning the whole array instead of one object
let me just add that when I console.log(res) it's returning the whole array immediately the moment I save. it's not even waiting for me to click on the button submit.
hello. 1) at which point is it returning the whole array? 2) can you update your question with your html template
It is returning it the moment I save the changes, not when I click the button
@omar check this StackBlitz Project. angular-hxzanu.stackblitz.io
|
0

There are a million ways to do this,but I'm going to recommend a number of best practices of what you should do, then provide extra information on why you should follow it instead of some custom approach.

  1. Use the async pipe

    • It will act like a "subscribe" on your component template (the html). There are a number of reasons to use this over manually subscribing, and setting a local variable yourself. The async pipe will automatically unsubscribe when the template is destroyed. Keep you from using takeUntil + a subject + ngOnDestroy (as seen and talked about here)
  2. Directly assign your observable from your service, to a component property that will be passed to the async pipe. This takes away any extra variables, and more or less directly "hooks up" your observable pipe from your service to the template.

// component-code
// the property we will 
public word$: Observable<Array<Word>>;

ngOnInit() {
  // the dollar sign after the variable is a convention to denote its an "observable"
  this.words$ = this.getWords()
}
private getWord(word: string): Observable<Word | undefined> {
  // the service method returns the list of words, or data
  return this.wordService.getWord(word)
    // we will use the map operator to take the list of words (which you said 
    // are returned in the "data"?
    .pipe(map((dat) => data.find((dataWord) => dataWord.spelling === word);
}

  1. Use the as and else syntax:
    • If your making an async request to the backend, what do you want to show to the user as it "comes back"?. Most of the time you want to show some loading spinner, or something to alert the user something is happening.
    • You don't need to use the as syntax in the below example, but if you want to call a function on the object, then you can now pass it. Otherwise your left with creating a property on the component

<!--component template-->
<div *ngIf="word$ | async as word; else showSpinner">
  {{word}}
</div>
<!-- this MUST be an ng-template to work with the ngIf-->
<ng-template #showSpinner>
  <div class="spinner"> </div>
</ng-template>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.