AngularJS + GAE not updating HTML - html

EDIT: Turns out the version being served was outdated - updating the version in app.yaml doesn't actually update the served version.
As the title says, I'm trying to upload changes to an AngularJS app to Google App Engine (Python, if it matters).
The referenced HTML files for each view however will not update and I'm not sure why.
Here's the app.yaml:
- url: /site/(.*\.(js|css|png|ico|txt))$
static_files: site/dist/\1
upload: site/dist/.*\.(js|css|png|ico|txt)$
login: required
secure: always
- url: /site/(.*\.html)$
static_files: site/dist/\1
upload: site/dist/.*\.html$
login: required
secure: always
expiration: '30s'
- url: /site/.*
static_files: site/dist/index.html
upload: site/dist/index.html
login: required
secure: always
And a couple of examples of HTML referenced in app.js:
// Routes
$routeProvider
.when('/users', {
templateUrl: 'users/users.html',
controller: 'UserCtrl',
activeTab: 'users',
reloadOnSearch: false
})
.when('/users/profile/:userId', {
templateUrl: 'users/profile.html',
controller: 'UserProfileCtrl',
activeTab: 'users'
})
.when('/users/new', {
templateUrl: 'users/create.html',
controller: 'UserCreateCtrl',
activeTab: 'users'
})
So the html is in dist/users/__.html or appropriate, with app.js residing under dist/
Updating these files, then doing a GAE update does not update the html. I've set a cache expiration of 30s, still not updating.
Is there anything I can do to force all html changes to be uploaded?
JS/CSS files have a version number appended to the end as part of the build process so they work fine, but as far as I can tell that's not possible to do for the html with angular routes.

Perhaps you previously had a longer cache setting for the .html files? In that case they could already be cached on the Google frontend servers. If you look at the response headers in your browser's network inspector you can see if they are indeed cached and perhaps what their age is. You might have to wait till they are evicted from the cache before you can see updates to them again.
In the mean time, try with different filenames and see if that does work.
Another trick you could try is to add a timestamp to the filename.
So instead of requesting 'users.html' you could request 'users.html?cachebuster=' + +new Date()

Related

Error Static file referenced by handler not found: dist/api/landing for Angular App deployed on Google Cloud

please help, I do not have experience deploying, I have been trying for days, bear with me. Thanks.
I have been working on a angular app with flask backend and both work proper locally, I need to deploy them. The server is written in flask and it is accessible via Postman. The page renders properly from "https://apt-trainer-279210.uc.r.appspot.com/" but on API call an error 404 not found when calling "api/landing" to my server. Going to the logs on GAE I see error.
Static file referenced by handler not found: dist/api/landing
I am guessing that its looking for file in the above path but it should be calling my server instead. Below is my app.yaml file for angular:
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /
static_files: dist/index.html
upload: dist/index.html
- url: /
static_dir: dist
skip_files:
- e2e/
- node_modules/
- src/
- coverage
- ^(.*/)?\..*$
- ^(.*/)?.*\.json$
- ^(.*/)?.*\.md$
- ^(.*/)?.*\.yaml$
- ^LICENSE
Also note that in the angular app I proxy to the server:
{
"/api": {
"target": "http://civil-planet-279210.uc.r.appspot.com" ,
"secure": true,
"logLevel": "debug",
"changeOrigin": true,
"pathRewrite": {
"^/api/*": ""
}
}
}
A Similar question was also posted but the user was using Cloud Endpoints while my server is in python flask. I could not use the solution.
Not sure if I should post the app.yaml for the python server as it is working properly.
Your assistance would be greatly appreaciated.
According to my understanding this is working as expected. According to the documentation about header element we may find in url part:
The URL pattern has some differences in behavior when used with the following elements:
static_dir
Uses a URL prefix. The regular express pattern should not
contain groupings when used with the static_dir element. All URLs that
begin with this prefix are handled by this handler, using the portion
of the URL after the prefix as part of the file path.
So calling .../api/landing will use the same logic: " using the portion of the URL after the prefix as part of the file path."
I am not sure what is your intention, but I think you should create the handler for the feature you want to invoke.
BTW you are using Python 2 which is not already not recommended and not supported. I would consider migration. You can see this at top of every page of documentation.
Was able to fix the issue with the following yaml - I was missing the third handler.
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /
static_files: dist/index.html
upload: dist/index.html
- url: /
static_dir: dist
- url: /.*
script: auto
secure: always
redirect_http_response_code: 301
skip_files:
- e2e/
- node_modules/
- src/
- coverage
- ^(.*/)?\..*$
- ^(.*/)?.*\.json$
- ^(.*/)?.*\.md$
- ^(.*/)?.*\.yaml$
- ^LICENSE

Dynamic routing with next export mode

We're using Next.Js in next export mode (static HTML export), and we need advanced dynamic routing.
Our routes will look like /[config1]/[config2]/[optionalConfig?]/page, where one segment is optional and the page names are fixed. For example a/b/c/page1 or a1/b1/page2. The pages need the configuration segment data to render.
I haven't found any way to do this with the built-in routing. I can do /pages/[config1]/[config2]/page1.tsx, but that optional segment seems to be an issue. Note that a custom server does not appear to be an option, as we have to use next export mode due to other constraints.
NOTE: We don't know the paths at build time; they represent part of our runtime configuration. This has to use client-side routing. (We do know the finite set of pages - say page1 ... page10 - but the routes to those pages will vary.)
I've tried switching to React Router, setting useFileSystemPublicRoutes: false and adding routes to pages/_app.tsx (Custom App). That almost works, but I see many 404s for on-demand-entries-utils.js in the console as well as some "Possible EventEmitter memory leak detected" warnings (in development mode).
Valid solutions (must work 100% client-side):
Way to do this with built-in routing
Example of integrating React Router with Next.Js
Alternative library (I've looked at next-routes but that hasn't been updated in 3 years)
UPDATE
We may be able to eliminate the requirement of an optional segment. However, it appears that we have to implement getStaticPaths and specify all of the routes. For example:
pages/[config]/foo.tsx
export async function getStaticPaths() {
// Runs at build time
return {
paths: [{ params: { config: 'xyz' } }],
fallback: false,
};
}
export async function getStaticProps(context) {
return {
props: {},
};
}
export default function FooPage(): JSX.Element {
return <div>FOO</div>;
}
This will generate
┌ ○ /
├ /_app
├ ● /[config]/foo
├ └ /xyz/foo
The issue is that we do not know the config at build time.
We need dynamic client-side routing. We'd like to stay with Next.js, as eventually we may be able to use SSR, but that's not an option at the moment.
You can create a catch-all route to grab the parameters, including the optional one, and then you'll need to render the right component based on that. So if you created:
pages/[...config].tsx
This is the same as:
pages/[...config]/index.tsx
Then in index.tsx, you can get the config as an array of strings in getStaticProps based on the url. So /config1/config2/optional is [config1, config2, optional] and /config1/config2 is [config1, config2].
So you can use this as a directory path of sorts if you need to add additional subpages under the known and optional paths.

Change swagger host and port serving it statically

Inspired by this sample repository, I'm generating a swagger output in json with protoc and serving it. However, for certain reasons I'm hosting the swagger content on a different port(:10000) than my REST api service(:8000).
I'm using the Go library statik to bundle up the swagger assets and serve them. It works, and a webpage is served when going to localhost:10000.
However, every cURL request swagger makes seems to be confined to just that - localhost:10000. The REST API lives on localhost:8081.
Serving swagger-ui with static content, how do I change the host/port for the REST api server?
I've tried going into the index.html of the swagger-ui content to add basePath as here, but with no luck. Every request is still made to :10000
window.onload = function() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: "./service.swagger.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout",
// I added this, but it did not change anything.
basePath: "localhost:8081"
})
// End Swagger UI call region
window.ui = ui}
</script>
Add host with value localhost:8081
Remove basePath, basePath is used to change the relative path after host i.e if your web server is hosted at /v1/ etc, then you can use basepath to change that
i am still trying to find out how to pass host value dynamically for production, stage, dev env

Html5 Offline app with angular not working offline

I have an Single Page html5 offline app with angularJs, Breeze and Asp.net MVC. The app is meant to store all the files in the cache and then just work off line. We do have a manifest files that lists all the files that the application needs including all the templates for angular to slot into the main page. To load the templates we are using standard angular routes. The app works just fine when there is a connection to the server, and this is because everytime angular fetches a template, it fetches it from the server even though the file is in the local cache. Once Angular has fetched the template once, if you load the same url again it works fine and loads it from the local cache.
Below is our cache manifest example( I have tried removing the Appendhash)
CACHE MANIFEST
# version 0.90
# #Url.Content("~/views/shared/_LayoutSPA.cshtml").AppendHash(Request)
# #Url.Content("~/views/portal/Index.cshtml").AppendHash(Request)
CACHE:
# AppendHash approach from ##ShirtlessKirk via http://bit.ly/12HlyCD to ensure the content manifest changes any time any page referencing it changes
Index
#Url.Content("~/Templates/jobSummaryNotes.html").AppendHash(Request)
#Url.Content("~/Templates/notfound.html").AppendHash(Request)
#Url.Content("~/Templates/orderInstall.html").AppendHash(Request)
#Url.Content("~/Templates/packages.html").AppendHash(Request)
#Url.Content("~/Templates/parties.html").AppendHash(Request)
#Url.Content("~/Templates/party.html").AppendHash(Request)
#Url.Content("~/Templates/property.html").AppendHash(Request)
#Url.Content("~/Templates/profit.html").AppendHash(Request)
#Url.Content("~/Templates/quote.html").AppendHash(Request)
#Url.Content("~/Templates/quotes.html").AppendHash(Request)
I have checked the cache in chrome and all the files etc are there.
below is our standard route config
.config(["$routeProvider", function ($routeProvider) {
'use strict';
// default root
$routeProvider.when("/", {
controller: "toriga.jobsController",
templateUrl: "templates/jobs.html"
});
$routeProvider.when("/notfound/", {
templateUrl: "templates/notfound.html"
});
$routeProvider.when("/epc/:id", {
controller: "toriga.epcController",
templateUrl: "templates/epc.html"
});
Some of the routes are with the parameters.
We are really confused to why angular does not fetch the template from the application cache and also why once you have visited the page, for example "epc", if you navigate to "epc" again it works as intended and does not go to the server.
Many thanks
Solved,
The problem is that manifest is case-sensitive, hence the address in the angular route should exactly match the entry in the maninfest. so for example
// default root
$routeProvider.when("/", {
controller: "toriga.jobsController",
templateUrl: "templates/jobs.html"
});
Should match manifest entry:
#Url.Content("~/templates/jobs.html")

Downloading json dummie file with $.ajax

I'm making the front end of a webpage where some json is needed for now I'm not doing the back so I made a file called it map.json and placed it on my server.
I'm working with node.js as a server so in the public folder I created a new folder named it jason and saved the file there.
Now I'm making an ajax call to this file, but the program isn't finding it, and when I go to public from the google chrome I don't see the json folder.
What do I have to do to be able to see this file and upload it as it was an ajax call to the server?
here is my jquery code, its in a file in public/javascript:
$.ajax('/../json/map.json', {
cache: false,
dataType: "json",
success: function(json) { ... code ... }
});
I really don't know how or what file should I modify in noje.js
Thanks!
The URL path used is technically invalid. Following a leading / with .. attempts to reach the parent directory of the domain's root path, which doesn't exist.
Though the browser may simply ignore the .., you should still choose one or the other -- either specify the path from root:
$.ajax('/json/map.json', {
// etc.
});
Or relative to the URL path of the current page (e.g., /some/page):
$.ajax('../json/map.json', {
// etc.
});
You've also stated that that the folder is named "jason" while the request includes /json/.... One may simply be a typo, but make sure they match.
And, assuming you're using the static() middleware, the URL will need to match the prefix specified (or lack of one):
app.use(express.static(__dirname + '/public'));
// $.ajax('/json/map.json', ...);
app.use('/public', express.static(__dirname + '/public'));
// $.ajax('/public/json/map.json', ...);