-1

Can anyone help me with this issue ? I am stuck on this for 2 days,....I really do not how to fix it....I built a web page(contains a table) using angular cli/angular5 and expressjs. I use mongoose mongodb as the database. Everything working fine on local. But When I uploaded the dist folder and deployed it to the azure web app, its table is empty. The error log looks like this:

HttpErrorResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "https://stringfr.azurewebsites.net/book", ok: false, …}
   error:
   error: SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse
    HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
    message: "Http failure during parsing for https://stringfr.azurewebsites.net/book"
    name:"HttpErrorResponse"
    ok:false
    status:200
    statusText:"OK"

Here is my temp website:"https://stringfr.azurewebsites.net". you can check the full error log by inspect.

I think this is something to do with this line in the book.component.ts. Here I get data from the database and use it on a simple html table. Note book_value is just a interface for me to a get a more structural data.

this.http.get<book_value>('/book').subscribe (
  data => this.books = data
);

Here is where I init the '/book'. in app.js

var express = require('express');
var path = require('path');
var logger = require('morgan');
var bodyParser = require('body-parser');


var book = require('./routes/book');
var app = express();
var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
//mongoose.connect('put ur own mongodb')
  // .then(() =>  console.log('connection succesful'))
   //.catch((err) => console.error(err));
mongoose.connect('mongodb://localhost/mean-angular5')
  .then(() =>  console.log('connection succesful'))
  .catch((err) => console.error(err));


app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({'extended':'false'}));
app.use(express.static(path.join(__dirname, 'dist')));
app.use('/books', express.static(path.join(__dirname, 'dist')));
app.use('/book', book);

In the ./routes/book.js

var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var Book = require('../models/Book.js');

/* GET ALL BOOKS */
router.get('/', function(req, res, next) {
  Book.find(function (err, products) {
    if (err) return next(err);
    res.json(products);
    console.log(products);
    console.log("products info above");
    console.log(res);
  });
});

Here is my schema in the ../models/Book.js:

var mongoose = require('mongoose');

var BookSchema = new mongoose.Schema({
  timestamp: String,
  question : String,
  answer : String
 });
 module.exports = mongoose.model('Book',BookSchema );

Since I am using dist folder. I use this web.config.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="AngularJS" stopProcessing="true">
          <match url="^(?!.*(.bundle.js|.bundle.map|.bundle.js.gz|.bundle.css|.bundle.css.gz|.png|.jpg|.ico|.svg|.eot|.woff|\​.woff2)).*$" />
          <conditions logicalGrouping="MatchAll"></conditions>
          <action type="Rewrite" url="/" appendQueryString="true" />
        </rule>
      </rules>
    </rewrite>
    <staticContent>
      <remove fileExtension=".svg" />
      <remove fileExtension=".eot" />
      <remove fileExtension=".woff" />
      <remove fileExtension=".woff2" />
      <mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
      <mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
      <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
      <mimeMap fileExtension=".woff2" mimeType="application/font-woff" />
    </staticContent>
  </system.webServer>
</configuration>

Note: There is not error showing on the azure log stream. Here is my app.module:

const appRoutes: Routes = [
  {
    path: 'books',
    component: BookComponent,
    data: { title: 'Book List' }
  },
  { path: '',
    redirectTo: '/books',
    pathMatch: 'full'
  }
];

@NgModule({
  declarations: [
    AppComponent,
    BookComponent,
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    CalendarModule,
    BrowserAnimationsModule,
    FormsModule,
    AccordionModule,
    PanelModule,
    ButtonModule,
    RadioButtonModule,
    DataTableModule,
    MultiSelectModule,
    DropdownModule,
    RouterModule.forRoot(
      appRoutes,
      { enableTracing: true } // <-- debugging purposes only
    )
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
Qi Lin
  • 77
  • 13
  • It looks like your book route isn't accessible. https://stringfr.azurewebsites.net/book doesn't work. Maybe you have it so regular http requests can't be seen, but you might want to turn that off for troubleshooting reasons if you do. Then you can see what the json looks like. – adprocas Mar 12 '18 at 18:28
  • Actually, if you read your error you'll see that this isn't a straight json string that /book is returning. It's a bunch of HTML and JavaScript and stuff. That's where your problem lies. – adprocas Mar 12 '18 at 18:33
  • Is this something to do with this : this.http.get('/book').subscribe ( data => this.books = data ); because this is the only place I use "/book", the "/book" is handling the get request to get all the book data from database. – Qi Lin Mar 12 '18 at 18:37
  • Or it is some problem to do with the dist folder? – Qi Lin Mar 12 '18 at 18:38
  • I don't know. I would suggest you check to make sure your routes are set up properly. It seems like a routing issue. Try looking at this documentation. https://angular.io/guide/router – adprocas Mar 12 '18 at 18:47
  • Thank you for responding. I read the documentation before. The '/book' is only for the usage of getting data from database. It is not a page, so there is not any component related to it in the app.module. And I have update my question with my app.module... – Qi Lin Mar 12 '18 at 19:09
  • I tried to comment out the usage of '/book' ...then the error are gone, but how can I get my data from the database...I am a newbie..if you can please take a look at my code. Thank you. – Qi Lin Mar 12 '18 at 19:11
  • I'm not an angular developer. But, it appears you're looking for a json response from the /book path. So, you need to make sure that endpoint is spitting out a json string. I'm sure there are other ways to do it, but it appears this is likely how you have it set up. – adprocas Mar 12 '18 at 19:24
  • Thank you, maybe it is a good idea for me to look for another way to get data from the database. – Qi Lin Mar 12 '18 at 20:16
  • @QiLin did you get the issue resolved or you change your database way? – Vipul Kumar Nov 21 '18 at 05:36

3 Answers3

1

Disclaimer: I've never used Azure.

It looks to me like Azure is rewriting all requests to / and serving Angular's index.html on every path.

How these kinds of rewrite rules usually work:

  1. Request comes in
  2. Azure parses the request, and sees if any rules apply. If so, it changes the request URL based on the redirect.
  3. The new edited request URL gets sent to Express.
  4. Express responds with the edited request URL's result.

It looks to me like when in step 2 Azure rewrites /book to /, then the /book URL is never hit.

I suggest you first try removing the rewrite rule and seeing if the /book URL sends the correct JSON response.

If it does not, check if /book/ with the trailing slash sends the right response. If it does, and /book does not, add a 5-line middleware to make Express think /book and /book/ mean the same thing.

boxmein
  • 865
  • 7
  • 19
  • Thanks a lot, I will try to do the above. – Qi Lin Mar 12 '18 at 19:14
  • I have tried, however in both cases, it gives this: "The resource you are looking for has been removed, had its name changed, or is temporarily unavailable." and I can access the table through '/' but I can't do it in '/books' anymore. I think I need that rewrite for it to read dist folder properly. Still thank you for responding to my question. – Qi Lin Mar 12 '18 at 19:34
0

have you tried pasting https://stringfr.azurewebsites.net/book into your broswer and seeing what returns?

If it's not JSON, that's your problem.

  • It says NavigationError {id: 1, url: "/book", error: Error: Cannot match any routes. I know this already.....it is my problem, but I can't solve it, that's why I am asking this question on here... – Qi Lin Mar 12 '18 at 18:33
0

Well, in Azure, your app runs on Microsoft IIS, and /book is an express route which is a backend Node.js app and it should be executed by the IIS module iisnode. So, you'd need to edit your web.config file to set the CGI handler to something like this:

<handlers>
    <!-- Indicates that the app.js file is a node.js site to be handled by the iisnode module -->
    <add name="iisnode" path="app.js" verb="*" modules="iisnode"/>
</handlers>

And also add the following rule to tell what the entry point is:

<!-- All other URLs are mapped to the node.js site entry point -->
<rule name="DynamicContent">
     <conditions>
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
     </conditions>
     <action type="Rewrite" url="app.js"/>
</rule>

And add this to tell that where the static content are:

<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
     <action type="Rewrite" url="public{REQUEST_URI}"/>
</rule>

See also:

Aaron Chen
  • 9,835
  • 1
  • 16
  • 28
  • I have tried above. When I deployed the dist folder, the error log are still the same.It still has the same error and that last adding conflicts with my original code, it also gives me 404. But, I think you are right about this..it has something to do with the web.config. I think the app.js is not running when I tries to get data from the database. Thank you for answering, – Qi Lin Mar 13 '18 at 15:07
  • Edit: it is not 404, its net::ERR_ABORTED. – Qi Lin Mar 13 '18 at 15:54
  • If you can, Can you take look at my code: here is my github link: https://github.com/QiiLin/Personal-Project-for-Chatbot or can you link me some resource for me to take a look. I am kind of know what is causing the issue, but don't know how to fix it. Is there a good guideline for me to construct a working web.config? – Qi Lin Mar 13 '18 at 18:44