4

When using Angular 5 with Flask and ng build --aot --watch, I am having major issues getting Angular's routing and refreshing the page to work.

I have come across many attempts to fix this, but none of them when applied to my project work (and the example projects provided when I try it there also do not seem to work).

What happens (depending on the thing I try) are these:

  1. It can't find the path at all and I get a Jinja2 error
  2. It can't find the document for localhost:5015/ (the port I'm using) and I get a 404 and a white screen
  3. It loads index.html, but upon refresh it gets a 404 (implying that the browser is attempting to fetch the page from the server, not using the Angular routing system)
  4. I get the same issue as this one: Syntax Error in Angular App: Unexpected token <

I am under the impression this is a normal issue with all SPAs and that the solution is to always redirect the server to index.html. We have done this (AFAIK), and attempted multiple ways to do this: Our structure is roughly the following:

- ProjectDir
  - reverseProxy_Calls
  - scripts
  - swagger_yaml_definitions
  - templates
    - e2e
    - dist
    - src
      - app

And our server.py contains this (among other stuff)

Swagger(app)

app.template_folder = "./templates/dist/"
app.static_folder = "./templates/dist/"
app.static_path = "./templates/dist/"
app.static_url_path = "./templates/dist/"
app.instance_path = "./templates/dist/"
config = settings.config()
config.read("settings.cfg")


@app.route('/', defaults={'path': ''}, methods=['GET', 'POST'])
@app.route('/<path:path>', methods=['GET', 'POST'])
def get_resource(path):  # pragma: no cover
    # If we are devmode, proxy through flask.
    if config.getKey("devmode") == True:
        url = "http://localhost:%s/%s" % (config.getKey('ng_port'), path)
        j = requests.get(url, stream=True, params=request.args)
        return make_response(j.text)
    # return the results
    # return render_template('dist/index.html')
    # return app.send_static_file("index.html")
    return send_from_directory('dist/', path)

if __name__ == '__main__':
    app.run(debug=True, port=int(config.getKey("port")))  # , host='0.0.0.0')

^ A variety of ways here show various attempts to handle this.

I have also looked at and tried projects that use variations of the following:

  • Flask Cli
  • Flask-Script
  • Flask-Bootstrap

None of them have solved this problem when I have tried them.

I have been told that using the hashRoute location strategy in Angular rather than the History PushState strategy will also work, however when I attempted to do that it had the same behavior of losing the page upon refresh (additionally we wish to use server side rendering in the future, and hashRoute location strategy prevents this possibility, among many other downsides).

Possibly related is that Flask seems to reload or re-render the page when it does find the index.html and routes initially, wiping anything printed to the browser dev console. I have seen this in some of the flask examples, but not all, and I'm uncertain what causes this.

When running via ng serve --aot --prod, things work exactly correctly and as expected. It's only when serving via Flask that things break down.

Apologies for the long question and thank you for your time in advance.

4
  • There's a lot going on here and it's really unclear what you're trying to do. Why proxy though Flask at all? Flask is essentially a router / web controller. It's designed to be proxied behind something else (such as nginx). The settings have it either call out to ng serve or just serve a static index.html (which is probably not what you want). Additionally you mention Jinja but you aren't making any calls to it at all. You also set some settings statically and then appear to load a settings.cfg file. Commented Apr 20, 2018 at 20:09
  • Yeah, so I've tried a variety of different things, and have taken over from where a senior dev left off (I am not a senior). The proxy through flask if dev mode was written by him in an attempt to allow using ng serve while still having the flask server. I believe the deploy will also have nginx. The flask server is being used as a way to handle CORS, the angular app will call to "/api/1/gettestdata" endpoint on the flask server, and the flask server will then verify auth and call to the appropriate backend server. The various commented out returns are example attempts to handle this by me. Commented Apr 20, 2018 at 20:15
  • Jinja2 error appears when you do either the render_template or some of the send static file things I attempted. We are not wanting to use Jinja2, it's just an error Flask throws when it attempts to parse something as Jinja2 I believe. Commented Apr 20, 2018 at 20:18
  • Example call in the Angular: getTestService(): Observable<any> { return this.httpClient.get<any>('api/1/testservice'); } This is taken from how we have done a project using AngularJS in the past with the following stack: ElasticSearch, Flask backend, nginx, flask localhost/server/revProxy/thing, AngularJS + ui-router library front end. As I understand it, we are basically doing the same thing, only with Angular5 replacing AngularJS. Commented Apr 20, 2018 at 20:25

1 Answer 1

1

I am under the impression this is a normal issue with all SPAs and that the solution is to always redirect the server to index.html. We have done this (AFAIK), and attempted multiple ways to do this

You also need to redirect all HTTP errors to index.html.

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

3 Comments

Oh, thank you. This sounds like the potential solution. I will look into how to do this. My first pass keeps generating werkzeug errors, but I'll look around on this front.
Yes, this was exactly the issue. Apologies for long time between responses, was dealing with having to unexpectedly replace my vehicle. Will mark as answer.
I've the same issue how to achieve this with respect to FLASK server like, how to redirect at server side

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.