Jeff
Jeff

Reputation: 4433

How to redirect after API call

I have an angular front end app and a golang api. The angular app is built (and runs fine). It makes a few calls to the go api which makes calls to an external service. After the calls to the external service, I want the frontend to redirect to a success page. I can't seem to get that to work in my Go code.

This is what I have (and works except for the redirect):

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/gin-contrib/static"
    "net/http"
    "io/ioutil"
    "strings"
    "encoding/json"
    "strconv"
    "net/http/cookiejar"
)

const BASE_ENDPOINT = "https://external.host.com/"
const FIRST_CALL_ENDPOINT = BASE_ENDPOINT + "first"
const SECOND_CALL_ENDPOINT = BASE_ENDPOINT + "second"


func main() {
    // create an http client with a cookie jar
    cookieJar, _ := cookiejar.New(nil)
    client := &http.Client{
        Jar: cookieJar,
    }

    router := gin.Default()
    // this is the default route for the front end.  The angular app will handle
    // all non-api calls
    router.Use(static.Serve("/", static.LocalFile("../frontend/dist", true)))

    // Routes
    api := router.Group("/")
    {
        // get post calls to this endpoint
        api.POST("/my/first", func(c *gin.Context) {

            userData := c.PostForm("userData")
            rawTextBody := "data=" + userData
            resp, err := client.Post(FIRST_CALL_ENDPOINT, "text/plain", strings.NewReader(rawTextBody))
            if err != nil {
                panic(err)
            }
            body, _ := ioutil.ReadAll(resp.Body)
            var data map[string]interface{}
            jsonErr := json.Unmarshal([]byte(body), &data)
            if jsonErr != nil {
                panic(jsonErr)
            }
            // data comes back as a "float64", is converted to an int, then to a string
            var jobId = strconv.Itoa(int(data["curjobId"].(float64)))
            moreUserData := c.PostForm("moreUserData")
            rawTextBodyCat := "secondUserData=" + moreUserData + "&jobid=" + jobId
            _, secErr := client.Post(SECOND_CALL_ENDPOINT, "text/plain", strings.NewReader(rawTextBodyCat))
            if secErr != nil {
                panic(secErr)
            }
            // TODO: need "successfully submitted" page. This already exists in the frontend angular server
            // I can manually go to that page. ('/my/success')

            // what i've tried:
            //http.Redirect(w, r, "/my/success", http.StatusSeeOther)
            //http.RedirectHandler( "/my/success", http.StatusSeeOther)

        })
    }

    router.NoRoute(func(c *gin.Context) {
        c.File("../frontend/dist/index.html")
    })

    // Run server
    router.Run(":8899")
}

In my code comments, you can see I've tried http.Redirect(w, r, "/my/success", http.StatusSeeOther) but I don't know how to call it in this context. I am not setting up a route listener, but just trying to trigger a redirect on demand. Should this be handled by the angular app somehow? How can I tell the angular app "all done"?

Upvotes: 2

Views: 4603

Answers (1)

vardius
vardius

Reputation: 6556

You can not redirect frontend client app with an API response. What you need to do is to handle this on the client side, and use your router to navigate to correct page.

What API does:

Redirect replies to the request with a redirect to url, which may be a path relative to the request path.

source

Which is simple instruction for your angular client what to do. Lets say in your $http success callback you call $location.url('/my/success') , which would use the Angular router to "redirect" to '/my/success'.

Upvotes: 3

Related Questions