0

I build REST API with Spring Boot and I use this API in react app.

I would like to create a new resource(POST) and right after creating it I would like to add a file to this resource (PUT). I don't do it in one request because I follow that answer

There is the POST request:

fetch(`http://localhost:8080/authors`, {
            method: 'post',
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            },
            body: JSON.stringify({
                //body
            })
        }).then(r => console.log(r))

From the server's point of view, I handle this url like this:

//URL: http://localhost:8080/authors
@PostMapping
ResponseEntity<Author> createAuthor(@RequestBody Author author) {
    var result = repository.save(author); //JpaRepository
    return ResponseEntity.created(URI.create("/" + result.getAuthorId())).body(result);
}

So I return response with Location header. My question is: How can I use this to send another request to the location this header points to ? As you seen above I used console.log to see what server give me as a response. This is it:

Response { type: "cors", url: "http://localhost:8080/authors", redirected: false, status: 201, ok: true, statusText: "", headers: Headers, body: ReadableStream, bodyUsed: false }
​
body: ReadableStream { locked: false }
​
bodyUsed: false
​
headers: Headers {  }
​​
   <prototype>: HeadersPrototype { append: append(), delete: delete(), get: get(), … }
​​​
   append: function append()
​​​
   constructor: function ()
​​​
   delete: function delete()
​​​
   entries: function entries()
​​​
   forEach: function forEach()
​​​
   get: function get()
  ​​​
   has: function has()
​​​
   keys: function keys()
​​​
   set: function set()
​​​
   values: function values()
​​​
   Symbol(Symbol.toStringTag): "Headers"
​​​
   Symbol(Symbol.iterator): function entries()
​​​
   <prototype>: Object { … }
​
ok: true
​
redirected: false
​
status: 201
​
statusText: ""
​
type: "cors"
​
url: "http://localhost:8080/authors"

There is no information about the Location header, so I don't know how to use it as the response doesn't contain it

Monoxyd
  • 406
  • 1
  • 7
  • 18
  • Grab the fetch response: `fetch(...).then(r => r.text()).then(url => { /* do stuff with url */ })` edit: if you actually need a header, you need `fetch(...).then(r => { /* read r.headers */ });` –  Sep 18 '21 at 11:50
  • @ChrisG I actually did, but there is no "location header" that I need – Monoxyd Sep 18 '21 at 11:59
  • You can inspect the server response in the browser's dev tools. Press F12 to see them, then switch to the console tab and make sure `xhr` is turned on. Run the request and check where the URL ends up. –  Sep 18 '21 at 12:01
  • Yes, with `xhr` I can see it but when I do this: console.log(r.headers.Location)` I get `undefined`. – Monoxyd Sep 18 '21 at 12:05
  • Based on the backend code it looks like the URL is in the body? Did you try the very first code line in my first comment? Also try `r.headers.get("Location")` instead. Example code: https://jsfiddle.net/3phbzj8x/ –  Sep 18 '21 at 12:08
  • When I do this: `.then(r => r.text()).then(url => console.log(url))` in my console is just my resource as JSON. There is nothing about url – Monoxyd Sep 18 '21 at 12:14
  • `r.headers.get("Location")` is `null` – Monoxyd Sep 18 '21 at 12:32
  • My fiddle shows how to list all available headers. It doesn't list all from the actual response though, it's possible you cannot access the Location header. Try adding the url to the data you're sending back and grabbing it that way. –  Sep 18 '21 at 14:10

1 Answers1

0

fetch returns a promise and you can use .then() to make any calls you want, it will be something like:

    fetch(url, { method: 'POST', redirect: 'follow'})
.then(response => {
    // another call or anything you want to do
})
.catch(function(err) {
    console.info(err + " url: " + url);
});
Asad Ashraf
  • 1,425
  • 8
  • 19