0

I am working on/extending TOH. I have an add method that wants to push the new Hero onto the array then return user to the list.

the result of the call to addHero is coming back as a JSON hero inside double ticks, so as a string.

i have read many articles which seem to point to

angular.toJson
or 
.map(response=> response.JSON())

These are not working.

Here is the excerpt from my heroes.component.ts

  add(name: string): void {
    name = name.trim();
    if (!name) { return; }
    this.heroService.addHero({ name } as Hero)
      .subscribe(hero =>
      {
        this.heroes.push(hero);
        this.location.go('/Heroes');
      }
      );
  }

and hero.service.ts This clearly returns a Hero object...

  addHero (hero: Hero): Observable<Hero> {
    return this.http.post<Hero>(this.heroesUrl, hero, httpOptions).pipe(
      tap((hero: Hero) => console.log(`added hero w/ id=${hero.id}`)),
      catchError(this.handleError<Hero>('addHero'))
    );
  }

Upon return, the result is successfully pushed to the array, but enclosed in quotes.

array entry pushed as a string

The UI evidence of this is that the list has a blank entry at the bottom because there is no .Name property on that final array element.

If i refresh the page, everyone gets loaded as json.

Simple question but I can not seem to find an answer. Have been through many S/O questions involving ng2, php, etc. but none seem to address ng6, or provide a clue I can take away. if they do, Im missing it.

2
  • 1
    What's the output when doing your console.log(`added hero w/ id=${hero.id}`)? Commented Jul 8, 2019 at 13:46
  • 1
    This was the issue. hero.id returns a null because the only property that has been initialized is hero.name. Id isnt even a property at that point. Real issue is the return type. Commented Jul 8, 2019 at 13:59

2 Answers 2

1

If you want to parse a json into a javascript object you can use JSON.parse(response.JSON())

I'm guessing response.JSON() is returning the response as json, which then needs to be parsed

Edit: you can probably just remove the map => response.JSON() . As angular httpClient already parses it

Sign up to request clarification or add additional context in comments.

1 Comment

yes, the map line didnt help. should not have been in this post. Inside the subscribe scope, i put this...var hero2 = JSON.parse(response.JSON); compiler complains about response. Could you possibly expand your answer to include the original code and show where this line would fit. The lightbulb in my head has yet to go off regarding how all the rxjs syntax works...
1

The issue was the return type of the routine in the service.

@youris question got me to look harder at the service.

The issue is that the default response is not coded correctly as utf8 and 'text/html'

Here is the corrected code.

Public Function add(mh As mHero) As CustomJsonStringResult

   Dim h As New TOHbos.Hero()
    h.name.Value = mh.name
    h.Save()
    Return JsonStringResultExtension.JSONString(Me, h.JSON, HttpStatusCode.OK)
End Function

the referenced JsonStringResultExtension is credited to @NKosi in this post. (Code included for ease of referece)

Web Api: recommended way to return json string

public static class JsonStringResultExtension {
   public static CustomJsonStringResult JsonString(this ApiController controller, string jsonContent, HttpStatusCode statusCode = HttpStatusCode.OK) {
        var result = new CustomJsonStringResult(controller.Request, statusCode, jsonContent);
        return result;
    }

    public class CustomJsonStringResult : IHttpActionResult {
        private string json;
        private HttpStatusCode statusCode;
        private HttpRequestMessage request;

        public CustomJsonStringResult(HttpRequestMessage httpRequestMessage, HttpStatusCode statusCode = HttpStatusCode.OK, string json = "") {
            this.request = httpRequestMessage;
            this.json = json;
            this.statusCode = statusCode;
        }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) {
            return Task.FromResult(Execute());
        }

        private HttpResponseMessage Execute() {
            var response = request.CreateResponse(statusCode);
            response.Content = new StringContent(json, Encoding.UTF8, "application/json");
            return response;
        }
    }
}

Making these changes, the result is json, its pushed to the array correctly, and shows up in the Heroes list correctly.

enter image description here

enter image description here

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.