Weirdest code ever

I’m trying to replace the location strategy by condition prod/dev

I console.log(IonicENV.mode) <= this loges true

 { provide: LocationStrategy, useClass: (IonicENV.mode == "prod") ? PathLocationStrateg : HashLocationStrategy }

Although IonicEnv.mode returns prod, so the condition is true. but it always goes into using HashlocationStrategy.
There is no logical explanation at all…

if I do

      { provide: LocationStrategy, useClass: (console.log(IonicENV.mode == "prod")) ? PathLocationStrategy : HashLocationStrategy }

Then everything works correctly on the server. it meets the true condition and goes into using pathLocationStrategy… Any explanations…anyone??

I’ve been scratching my head 2 days straight for this, it’s like all programming principles don’t apply anymore…

You’re missing the colon.

Hacking tip:

never use a ternary operator when your code has bugs. 99% chance the bug lies in a malformed operator.

Sorry, it’s not the colon, I copied it wrong, just got corrected lol

cool

and +1 on the title of your post. :slight_smile:

not sure if this will help but have you tried === instead of == for exact match?

yeah === appears to have the same effect as == , so its false and starts to use hashStrategy, but it should be true and use pathlocationStrategy

Maybe “IonicENV” isn’t defined when the app is booting? Have u try to write one strategy and to use the flag in it?

Yeah I thought it could had been undefined but I couldn’t test it, it’s in the condition block, then I tried to console log it and it just worked…

console.log is maybe not executed at boot time but for some reason later on when actually the variable was defined in the meantime?

just some idea really I don’t know, just share some thoughts in case that would give you some better idea

is that a v3 or v4 app? what’s “IonicENV”?

Got it working by doing a toString() on a string (What the heck??)


let isProd: boolean = IonicENV.mode == "prod";  
let isProdToString: boolean = IonicENV.mode.toString() == "prod";  

console.log(isProd); // this logs true
console.log(isProdToString); // this logs true as well

BUT

isProd ? PathLocationStrateg : HashLocationStrategy //Fails and goes into using Hash (We saw isProd logged true)

isProdToString ? PathLocationStrateg : HashLocationStrategy //Pass and goes into using Path

It’s like programming logic doesn’t apply anymore, this doesn’t make sense at all …

BTW, this is Ionic 3, IonicEnv is a custom Environment variable like this

export const IonicENV = {
mode: ‘prod’
}

then maybe it’s what @jjdev said here above, using === instead of == ?

Tried === and == they all failed… they went to use hashStrategy

copy/paste or there is a typo in ‘prod’, you pasted but I was expecting '?

I copy pasted it, it was doing some rich text converting…some weird font formatting it’s just a single quote

Mmmh I’m out of idea then, sorry

Thanks for your help anyways,
Here is the bigger picture of what’s happening:

let isProd: boolean = IonicENV.mode == “prod”;

console.log(isprod); <= this logs true
@NgModule({
providers: [ { provide: LocationStrategy, useClass: isProd ? PathLocationStrateg : HashLocationStrategy }
]
})

this isProd is false somehow on the server when I do --prod build

unless I do IonicENV.mode.toString() == “prod” OR IonicENV.mode.valueOf() == “prod”

I hope somehow someone will figure this out… this is a mystery now

@jfan29 I would advise you to avoid using expressions inside annotations, because they generate code at compile time (not runtime) when compiling with AOT and that could lead to very weird issues (that I already had the “luck” to experience). I’m thinking your code might be the same case. What you see during the console.log() is the runtime value, but how it defined the value at compile time I don’t know.

This is something I wrote to a guy that had weird issues when compiling with AOT (when you run with prod, it uses AOT) when defining firebase params retrieved from environment variables from a file that has its path defined during build time (unfortunately, the ngc and consequently aot is also run in the build time, and it was before the webpack phase, causing the error):

The thing is, when angular runs with AOT, the contents in the modules are precompiled when ngc runs (maybe you saw some problems like arrow functions in modules, that you have to use function explicitely, constants and so on)

It seems this pre-compilation uses the default value of ENV (environment.ts), because it happens before webpack runs

ngc started …
ngc finished in 8.56 s …
webpack started …
using DP_ENV:dev
webpack finished in 39.20 s

I even changed environment.ts to environment.prod.ts, and run, it gave me error in the ngc step, because it could not find the file (so the ngc uses the ENV before it was defined correctly)

without aot the modules are not pre-compiled, so the environment is correct

The solution here was instead of defining the variable path in the webpack phase, use a json file to store environment data and copy the raw json file of the correct environment to the correct directory (that has a file environment.ts) BEFORE the ngc phase.

There is only one environment.ts that is like:

import { Environment } from './environment.model';
import * as data from './environment.json';

export const ENV: Environment = <any>data;

(the correct json file is moved in the build stage)

This is the repository he created that solved the issue:

I don’t know if your issue is similar, but based on the weird errors you got it seems like it. You should pay attention to where you are exporting your environment variables, and if it will be available at the build stage and when.

As a rule of thumb, I advise to whenever possible avoid variables and functions inside annotations (errors in such cases can be very misleading and hard to find the cause).

2 Likes