8

I am trying to deploy an angular 6 app on azure app service platform (windows machine). The app itself is just a new angular app (basic code generated from ng new appname). I have added some minor code following this tutorial in order to use a config file and leverage variable substitution in vsts release pipelines - manage settings for an angular app with vsts.

These are the code changes I have made to the generated app. In app.module.ts

export function initializeAppSettings(appSettings: AppSettings) {
  return () => appSettings.load();
}

...

providers: [AppSettings, {
    provide: APP_INITIALIZER,
    useFactory: initializeAppSettings,
    deps: [AppSettings],
    multi: true
  }]

For my appsettings.ts file

export interface AppConfiguration {
  apiUrl: string;
}

@Injectable()
export class AppSettings {
  static config: AppConfiguration;

  constructor(private http: HttpClient) {}

  load(): Promise<any> {
    const appSettingsJson = environment.production ? 'assets/appsettings.json' : 'assets/appsettings.local.json';
    return new Promise<any>(((resolve, reject) => {
      this.http.get<AppConfiguration>(appSettingsJson)
        .toPromise()
        .then(result => {
          AppSettings.config = result;
          resolve();
        }).catch(reason => {
          reject(`unable to load settings file ${appSettingsJson} due to ${JSON.stringify(reason)}`);
      });
    }));
  }
}

In my angular.json file I have

"assets": [
              "src/favicon.ico",
              "src/assets",
              "src/web.config"
            ]

And the following web.config file

<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="Angular" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="/" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

I have a single setting in my src/assets/appsettings.json file atm

{
  "apiUrl": "https://localhost:5001/api/"
}

This setup works completely fine when running locally using ng serve or even deployed to local IIS using ng build. I use the loaded settings in my app.component.ts and app.component.html to verify that it loads correctly. But when I deploy the app to azure I get a 404 error.

ERROR unable to load settings file assets/appsettings.local.json due to {"headers":{"normalizedNames":{},"lazyUpdate":null},"status":404,"statusText":"Not Found","url":"https://mydomain/assets/appsettings.local.json","ok":false,"name":"HttpErrorResponse","message":"Http failure response for https://mydomain/assets/appsettings.local.json: 404 Not Found","error":"The resource you are looking for has been removed, had its name changed, or is temporarily unavailable."}

I have tried explicitly adding the individual appsettings.json file to my assets array in angular.json and have also tried with and without a web.config file. If I deploy just a basic angular app to azure (i.e. without the additional code to load the appsettings.json file) it works (even without a web.config file). I am pretty new to angular (and web development in general) and have searched everywhere I could for a solution but nothing has fixed it so far.

2
  • 3
    Did you verified that the appsettings.local.json is within wwwroot/assets/appsettings.local.json? Also please try to add <staticContent><mimeMap fileExtension=".json" mimeType="application/json" /></staticContent> in your web.config before the <rewrite> tag. Commented Sep 29, 2018 at 18:14
  • the <staticContent><mimeMap fileExtension=".json" mimeType="application/json" /></staticContent> did the trick. Thanks Commented Sep 29, 2018 at 23:45

1 Answer 1

14

Per @Martin Brandl comment adding the following to my web.config file did the trick. Thanks.

<staticContent><mimeMap fileExtension=".json" mimeType="application/json" /></staticContent>
Sign up to request clarification or add additional context in comments.

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.