How can I serve data to front-end in Angular universal App from a server different from ExpressJS server provided by Angular universal? - node.js

I am having an issue with my Angular SSR App that is still in development stage. It's a routing issue. FYI, I am new in Angular (or web dev). The problem is, I can start SSR server and it will work fine if the route on the browser address bar is pointing to static page, that's, a page/component that doesn't fetch data from the backed; I can navigate to any route without any issues. But if I start the SSR server when the link on the browser address bar is pointing to a route that fetches data from the backend, it won't work. The same thing happens when I reload. The browser goes on loading without displaying anything and the terminal shows the error message below like it's looping until the server crashes.
ERROR HttpErrorResponse {
headers: HttpHeaders {
normalizedNames: Map {},
lazyUpdate: null,
headers: Map {}
},
status: 0,
statusText: 'Unknown Error',
url: 'http://localhost:4000/http://localhost:3000/api/posts?pagesize=2&page=1
,
ok: false,
name: 'HttpErrorResponse',
message: 'Http failure response for http://localhost:4000/http://localhost:30
0/api/posts?pagesize=2&page=1: 0 Unknown Error',
error: ProgressEvent {
type: 'error',
target: XMLHttpRequest {
onloadstart: null,
onprogress: null,
onabort: null,
onerror: null,
onload: null,
ontimeout: null,
onloadend: null,
_listeners: [Object],
onreadystatechange: null,
_anonymous: undefined,
readyState: 4,
response: null,
responseText: '',
responseType: 'text',
responseURL: '',
status: 0,
statusText: '',
timeout: 0,
upload: [XMLHttpRequestUpload],
_method: 'GET',
_url: [Url],
_sync: false,
_headers: [Object],
_loweredHeaders: [Object],
_mimeOverride: null,
_request: null,
_response: null,
_responseParts: null,
_responseHeaders: null,
_aborting: null,
_error: null,
_loadedBytes: 0,
_totalBytes: 0,
_lengthComputable: false
},
......
.....
....
....
lengthComputable: false,
loaded: 0,
total: 0
}
}
<--- Last few GCs --->
[4452:0000002EB0A8B870] 320685 ms: Mark-sweep 1982.1 (1990.6) -> 1981.2 (1990
6) MB, 1846.0 / 0.2 ms (average mu = 0.093, current mu = 0.015) allocation fai
ure scavenge might not succeed
[4452:0000002EB0A8B870] 322582 ms: Mark-sweep 1982.1 (1990.6) -> 1981.3 (1990
6) MB, 1785.5 / 0.3 ms (average mu = 0.077, current mu = 0.059) allocation fai
ure scavenge might not succeed
<--- JS stacktrace --->
==== JS stack trace =========================================
0: ExitFrame [pc: 00007FF7AB40D31D]
Security context: 0x004c643008d1 <JSObject>
1: createRenderer [00000150847C9A91] [C:\****\****\Desktop\MEAN STACK\Ng-1
\blog\dist\blog\server\main.js:~1] [pc=000003A6BF0102C6](this=0x02a68959f539 <p
atform_server_ServerRendererFactory2 map = 0000036DB8EC5ED9>,0x012cea722c29 <HT
LButtonElement map = 00000383BFA19079>,0x0298c6e98e51 <Object map = 0000019ACF0
1339>)
2: addComponentLogic(aka ad...
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - Java
cript heap out of memory
1: 00007FF7AA7D286F napi_wrap+119263
2: 00007FF7AA779536 v8::internal::OrderedHashTable<v8::internal::OrderedHashSe
,1>::NextTableOffset+38102
3: 00007FF7AA77A336 node::OnFatalError+438
4: 00007FF7AAFB7B3E v8::Isolate::ReportExternalAllocationLimitReached+94
5: 00007FF7AAF9FCF1 v8::SharedArrayBuffer::Externalize+833
6: 00007FF7AAE514CC v8::internal::Heap::EphemeronKeyWriteBarrierFromCode+1436
7: 00007FF7AAE5C710 v8::internal::Heap::ProtectUnprotectedMemoryChunks+1312
8: 00007FF7AAE59224 v8::internal::Heap::PageFlagsAreConsistent+3204
9: 00007FF7AAE4EA23 v8::internal::Heap::CollectGarbage+1283
10: 00007FF7AAE4D094 v8::internal::Heap::AddRetainedMap+2500
11: 00007FF7AAE6E3DD v8::internal::Factory::NewFillerObject+61
12: 00007FF7AABD19D1 v8::internal::interpreter::JumpTableTargetOffsets::iterato
::operator=+1665
13: 00007FF7AB40D31D v8::internal::SetupIsolateDelegate::SetupHeap+546925
14: 000003A6BF0102C6
npm ERR! code ELIFECYCLE
npm ERR! errno 134
npm ERR! blog#0.0.0 serve:ssr: `node dist/blog/server/main.js`
npm ERR! Exit status 134
npm ERR!
npm ERR! Failed at the blog#0.0.0 serve:ssr script.
npm ERR! This is probably not a problem with npm. There is likely additional lo
ging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\Tony\AppData\Roaming\npm-cache\_logs\2021-08-24T16_40_37_
55Z-debug.log
How can I solve this issue? This is my Angular SSR below:
import 'zone.js/dist/zone-node';
const domino = require('domino');
// const proxyApp = require('./Backend/app');
import { ngExpressEngine } from '#nguniversal/express-engine';
import express from 'express';
import { join } from 'path';
import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF } from '#angular/common';
import { existsSync } from 'fs';
// import { createProxyMiddleware } from 'http-proxy-middleware';
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), 'dist/blog/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
// Shim for the global window and document objects.
const windowObj = domino.createWindow(indexHtml);
global.window = windowObj;
global.document = windowObj.document;
global.self = windowObj;
global.IDBIndex = windowObj.IDBIndex;
global.navigator = windowObj.navigator;
global.getComputedStyle = windowObj.getComputedStyle;
// Our Universal express-engine (found # https://github.com/angular/universal/tree/master/modules/express-engine)
server.engine('html', ngExpressEngine({
bootstrap: AppServerModule,
}));
server.set('view engine', 'html');
server.set('views', distFolder);
// Example Express Rest API endpoints
server.get('/api/**', (req, res) => {
res.status(404).send('data requests are not yet supported');
});
// re-route requests to /api/ to REST api
// server.use('/api/**', createProxyMiddleware({ target: 'http://localhost:8000', changeOrigin: true }));
// server.use(proxyApp);
// Serve static files from /browser
server.get('*.*', express.static(distFolder, {
maxAge: '1y'
}));
// console.log(appRoutes);
// All regular routes use the Universal engine
server.get('*', (req, res) => {
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
});
return server;
}
function run(): void {
const port = process.env.PORT || 4000;
// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}
export * from './src/main.server';
And this is the excerpt from my NodeJs/ExpressJs server below:
const express = require('express');
const path = require('path');
const cors = require('cors');
const mongoose = require('mongoose');
const config = require('./config');
const app = express();
const { db: { URL } } = config;
// const Post = require('./models/post');
const postsRouter = require('./routes/posts');
const userAuthRouter = require('./routes/user');
const adminAuthRouter = require('./routes/admin');
// const commentsRouter = require('./routes/comments');
const topicRouter = require('./routes/topic');
// MongoDB database settings
// Grab mongoDB Authentication password from env. var with obj destructuring and pass it on to mongoose.
const connectionOptions = { useUnifiedTopology: true, useNewUrlParser: true, useCreateIndex: true, /*useFindAndModify: false*/ };
// console.log(URL);
mongoose.connect(URL, connectionOptions )
.then(() => {
console.log('Connected Database');
})
.catch((err) => {
console.log('Connection Failed: ' + err);
});
const whitelist = ['http://localhost:4200', 'http://localhost:4000'];
const corsOptions = {
origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
}
};
app.use(express.urlencoded({extended: true})); // Parse URL-encoded bodies
app.use(express.json());
// app.use(cors())
app.use(cors({ origin: corsOptions }));
app.use(userAuthRouter);
app.use(postsRouter);
app.use(adminAuthRouter);
// app.use(commentsRouter);
app.use(topicRouter);
app.use('/images', express.static(path.join('Backend/images')));
module.exports = app;
I am adding additional info. The postsRouter and api/posts and the route displayed when ng serve is used are shown below:
// Get all Posts handler
exports.getPosts = (req, res, next)=> {
async.parallel({
posts: function(callback) {
const pageSize = +req.query.pagesize;
const currentPage = +req.query.page;
const topic = req.query.topic;
// Get All Posts
if (pageSize && currentPage && topic) {
Post.find({'topic': topic})
.skip(pageSize * (currentPage - 1))
.limit(pageSize)
.sort({publishDate: 'desc'})
.exec(callback);
}
// Group Post Based On Topic
if (pageSize && currentPage && !topic) {
// console.log(topic + " : " + id + ' 2nd');
Post.find({}, ' -topicID')
.skip(pageSize * (currentPage - 1))
.limit(pageSize)
.sort({publishDate: 'desc'})
.exec(callback);
}
},
postCount: function(callback) {
Post.countDocuments(callback);
}
},
function(err, results) {
if (err) {
return res.status(500).json({message: 'ERROR: Fetching Posts Failed!'});
}
res.status(200).json({
posts: results.posts,
postCount: results.postCount,
});
});
};
// Post service: Angular
getPosts(groupedPostTopic = '', postsPerPage?: number, currentPage?: number): void {
// Backend Params for pagination
const placeHolder = groupedPostTopic ? `/posts?topic=${groupedPostTopic}&` : '/posts?';
const queryParam = `pagesize=${postsPerPage}&page=${currentPage}`;
// Call to the server
const posts$ = this.http.get<{posts: Post[], postCount: number}>(BACKEND_URL + placeHolder + queryParam)
.pipe(map((postData) => {
return { posts: postData.posts.map((post: any) => {
const textStyle = this.dateTextStyle(post.publishDate);
return {
id: post._id,
topic: post.topic,
title: post.title,
postIntro: post.postIntro,
content: post.content,
imagePath: post.imagePath,
dateTextStyle: textStyle,
publishDate: post.publishDate,
creator: post.creator,
comments: post.comments
};
}),
postCount: postData.postCount
};
}));
// Activate spinner service until data arrival
this.isLoadingService.showContentUntilCompleted(posts$)
.subscribe(transformedPosts => {
this.posts = transformedPosts.posts;
this.postCount = transformedPosts.postCount;
// Data stored to be Observed using BehaviorSubject and/or asObservable() from rsjx
this.subject.next({posts: [...this.posts], postCount: transformedPosts.postCount});
});
}
// Displayed route when 'ng serve' is used
http://localhost:4200/posts
***OR***
http://localhost:4200/posts/:pageNo // For pagination
Thanks in advance!

Related

Export JSON from i18next to the client

I'm trying to export a JSON locale file from i18next to a link as an API to use on the client. The problem is that it only exports the locale that is specified in "fallbackLng", which is 'en'. How can I make it detect the locale from the "detection_options" so that the right locale is loaded and exported on the API?
// app.js
var detection_options = {
// order and from where user language should be detected
order: [/*'path', 'session', */ 'querystring', 'cookie', 'header'],
// keys or params to lookup language from
lookupQuerystring: 'lng',
lookupCookie: 'i18next',
lookupHeader: 'accept-language',
lookupSession: 'lng',
lookupPath: 'lng',
lookupFromPathIndex: 0,
// cache user language
caches: false,
}
// i18next configuration
const i18next = require('i18next');
const Backend = require('i18next-fs-backend');
const middleware = require('i18next-http-middleware');
i18next.use(Backend)
.use(middleware.LanguageDetector)
.init({
debug: true, // debug option shows that "zh-hant" is loaded correctly when the Chinese site is accessed.
detection: detection_options,
fallbackLng: ['en', 'zh'],
backend: {
loadPath(lng, ns) {
if (lng === 'zh' || lng === 'zh-HK' || lng === 'zh-TW') {
return path.join(__dirname, 'locales/zh-hant.json');
} else if (lng === 'en-US') {
return path.join(__dirname, 'locales/en.json');
}
return path.join(__dirname, 'locales/{{lng}}.json');
}
}
})
app.use(middleware.handle(i18next));
const localeController = require('../controllers/locale');
app.get('/locale', localeController.getLocale);
// locale.js
exports.getLocale = async (req, res, next) => {
var i18next = require('i18next');
res.status(200).json(
i18next.t('tree', { returnObjects: true })
)
}
Use the t function from within the request object, like:
https://github.com/i18next/i18next-http-middleware/issues/51#issuecomment-1094851968

Use fileSystem on an API Route with NextJS deployed on Vercel

I need to use fileStystem methods as readdirSync on an API Route in NextJS. It works locally but when deployed on Vercel, the request responds with a 500 status code.
This is Vercel's Funcion Logs:
catch Error: ENOENT: no such file or directory, scandir '/var/task/_posts'
at Object.readdirSync (fs.js:1043:3)
at getAllArticles (/var/task/.next/server/chunks/230.js:135:67)
at __WEBPACK_DEFAULT_EXPORT__ (/var/task/.next/server/pages/api/search.js:37:93)
at Object.apiResolver (/var/task/node_modules/next/dist/server/api-utils.js:101:15)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async Server.handleApiRequest (/var/task/node_modules/next/dist/server/next-server.js:770:9)
at async Object.fn (/var/task/node_modules/next/dist/server/next-server.js:661:37)
at async Router.execute (/var/task/node_modules/next/dist/server/router.js:205:32)
at async Server.run (/var/task/node_modules/next/dist/server/next-server.js:841:29)
at async Server.handleRequest (/var/task/node_modules/next/dist/server/next-server.js:292:20) {
errno: -2,
syscall: 'scandir',
code: 'ENOENT',
path: '/var/task/_posts'
}
This is the API Route itself (/pages/api/search.ts):
export default (req: NextApiRequest, res: NextApiResponse) => {
const { query } = req;
try {
if (query.q) {
const posts = getAllArticles(ArticleTypes.POSTS, ['slug', 'href', 'title', 'category'], {
hints: {
hint: query.q as string,
fields: ['title', 'category'],
},
}).map((post) => post.data);
const projects = getAllArticles(ArticleTypes.PROJECTS, ['slug', 'href', 'title', 'category', 'technologies'], {
hints: {
hint: query.q as string,
fields: ['title', 'category', 'technologies'],
},
}).map((project) => project.data);
res.status(200).json({
...(posts.length > 0) && { posts },
...(projects.length > 0) && { projects },
});
} else {
res.status(422).send('El parámetro "q" es necesario.');
}
} catch (e) {
res.status(500).send('Ha ocurrido un error mientras se intentaba hacer la búsqueda.');
}
};
And this is the getAllArticles() function used in it:
export const getAllArticles = (
type: ArticleTypes,
items?: string[],
filters?: IFilters,
): IArticle[] => {
const articlesPath = join(process.cwd(), `_${type}`);
const articlesNames = fs
.readdirSync(articlesPath)
.filter((path) => /\.mdx$/.test(path));
const mergedItems: string[] = Array.from(new Set([
...(items && items.length > 0) ? items : [],
...(filters?.hints && filters.hints.fields.length > 0) ? filters.hints.fields : [],
]));
const allArticles = articlesNames
.map((article) => getArticle(type,
path.parse(article).name,
mergedItems.length > 0
? mergedItems
: undefined));
const filteredArticles = filterArticles(type, allArticles, filters);
return filteredArticles;
};
So I am currently using fs.readdirSync for reading .mdx files. As I noted before, this runs perfectly well locally but not when deployed on Vercel. Do I nees to configure any kind of config files or anything?
Thank you so much!

TypeError: resolver is not a function in `next-connect`

I have a project using next-connect & twitter-api-v2.
I have a handler which calls 2 get routes like:
export default handler()
.get('/twitter/generate-auth-link', generateAuthLink)
.get('/twitter/get-verifier-token', getVerifierToken)
The handler looks like follows:
import { NextApiResponse } from 'next'
import cookieSession from 'cookie-session'
import nc from 'next-connect'
import { ironSession } from 'next-iron-session'
import { error } from 'next/dist/build/output/log'
import { NextIronRequest } from '../types/index'
const COOKIE_SECRET = process.env.COOKIE_SECRET
const SESSION_SECRET = process.env.SESSION_SECRET
const IS_PRODUCTION = process.env.NODE_ENV !== 'development'
/**
* Create an API route handler with next-connect and all the necessary middlewares
*
* #example
* ```ts
* export default handler().get((req, res) => { ... })
* ```
*/
function handler() {
if (!COOKIE_SECRET || !SESSION_SECRET)
throw new Error(
`Please add COOKIE_SECRET & SESSION_SECRET to your .env.local file!`
)
return nc<NextIronRequest, NextApiResponse>({
onError: (err, _, res) => {
error(err)
res.status(500).end(err.toString())
},
})
.use(
cookieSession({
name: 'session',
keys: [COOKIE_SECRET],
maxAge: 24 * 60 * 60 * 1000 * 30,
secure: IS_PRODUCTION && !process.env.INSECURE_AUTH,
signed: IS_PRODUCTION && !process.env.INSECURE_AUTH,
})
)
.use(
ironSession({
cookieName: 'mysite-session',
password: SESSION_SECRET,
// if your localhost is served on http:// then disable the secure flag
cookieOptions: {
secure: IS_PRODUCTION,
},
})
)
}
export default handler
I think I'm doing next-connect right but why do I get an error when I try to do simple fetch in the client like:
const res = await fetch('/api/twitter/generate-auth-link');
console.log({res})
The backend gives the following error:
error - TypeError: resolver is not a function
at Object.apiResolver (/~/twitter-api-v2-3-legged-login-using-next-connect/node_modules/next/dist/server/api-utils.js:101:15)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async DevServer.handleApiRequest (/~/twitter-api-v2-3-legged-login-using-next-connect/node_modules/next/dist/server/next-server.js:770:9)
at async Object.fn (/~/twitter-api-v2-3-legged-login-using-next-connect/node_modules/next/dist/server/next-server.js:661:37)
at async Router.execute (/~/twitter-api-v2-3-legged-login-using-next-connect/node_modules/next/dist/server/router.js:205:32)
at async DevServer.run (/~/twitter-api-v2-3-legged-login-using-next-connect/node_modules/next/dist/server/next-server.js:841:29)
at async DevServer.run (/~/twitter-api-v2-3-legged-login-using-next-connect/node_modules/next/dist/server/dev/next-dev-server.js:355:20)
at async DevServer.handleRequest (/~/twitter-api-v2-3-legged-login-using-next-connect/node_modules/next/dist/server/next-server.js:292:20) {
page: '/api/twitter/generate-auth-link'
}
I have made a complete repro → https://github.com/deadcoder0904/twitter-api-v2-3-legged-login-using-next-connect
All I want to do is perform steps of 3-legged Oauth using twitter-api-v2. The steps are given on https://github.com/PLhery/node-twitter-api-v2/blob/master/doc/auth.md
How do I solve this?
I removed index.ts file from pages/api/twitter/ & used default export in both pages/api/twitter/generate-auth-link & pages/api/twitter/get-verifier-token.
This solved it!

Query parameters in express 4 give me a "No default engine was specified" error

I am developing a web app using the MEAN stack (no Mongo for now)
I am trying to pass the name of a file on the server using a query paramerer, the error happens when i get :
"localhost:8080/api/result?filename=for-debug-file-name"
It is working well if I remove the console.log() right below
But when I get the query parameter it gets me the "Error: No default engine was specified and no extension was provided”.
(This route correspond to api/result)
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
console.log(req.query('filename')); // ERROR
res.status(200).json({ "json-test": 42 });
})
module.exports = router;
Here are my angular routes :
const appRoutes: Routes = [
{
path: 'result',
component: ResultComponent,
},
{
path: 'upload',
component: UploaderComponent,
},
{
path: '',
redirectTo: '/upload',
pathMatch: 'full'
}];
And here is my ResultComponent.ts :
ngOnInit() {
this.getParsedDocumentData('for-debug-file-name');
}
getParsedDocumentData(fileName: string): Observable<string[]> {
let params = new URLSearchParams();
params.append('filename', fileName);
let options = new RequestOptions({ params: params });
return this.http.get('http://localhost:8080/api/result/', options)
.map(res => res.json())
.catch(this.handleError);
}
private handleError (error: any) {
return Observable.throw(error);
}
I would really appreciate your help as I have been stuck for 4 hours.
Thanks.
query method in request object does not exists. Instead use query property to access filename parameter.
console.log(req.query.filename);
Reference

localhost REST API request error ionic2 angular2

I am making a get/post request to my locally hosted REST API server in an Ionic 2 app. The errow below shows up afer a couple of seconds.
3 387557 group EXCEPTION: Response with status: 0 for URL: null
4 387558 error EXCEPTION: Response with status: 0 for URL: null
5 387558 groupEnd
6 387568 error Uncaught Response with status: 0 for URL: null, http://localhost:8100/build/js/app.bundle.js, Line: 88826
I am able to make a successful curl request to the local server. Here is my code for reference.
app.js
var express = require("express");
var mysql = require("mysql");
var bodyParser = require("body-parser");
var SHA256 = require("sha256");
var rest = require("./REST.js");
var app = express();
function REST(){
var self = this;
self.connectMysql();
};
REST.prototype.connectMysql = function() {
var self = this;
var pool = mysql.createPool({
connectionLimit : 100,
host : 'host',
user : 'user',
password : 'password',
database : 'database',
debug : false
});
pool.getConnection(function(err,connection){
if(err) {
self.stop(err);
} else {
self.configureExpress(connection);
}
});
}
REST.prototype.configureExpress = function(connection) {
var self = this;
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var router = express.Router();
app.use('/api', router);
var rest_router = new rest(router,connection,SHA256);
self.startServer();
}
REST.prototype.startServer = function() {
app.listen(3000, function() {
console.log("All right ! I am alive at Port 3000. OKAY BUDDY");
});
}
REST.prototype.stop = function(err) {
console.log("ISSUE WITH MYSQL n" + err);
process.exit(1);
}
new REST();
REST.js
var mysql = require("mysql");
function REST_ROUTER(router, connection, SHA256) {
var self = this;
self.handleRoutes(router, connection, SHA256);
}
REST_ROUTER.prototype.handleRoutes= function(router,connection,SHA256) {
router.get("/",function(req,res){
res.json({'foo': 'bar'});
});
});
login.js (component)
import {Component} from '#angular/core';
import {NavController} from 'ionic-angular';
import {AuthProvider} from '../../providers/auth/auth';
/*
Generated class for the LoginPage page.
See http://ionicframework.com/docs/v2/components/#navigation for more info on
Ionic pages and navigation.
*/
#Component({
templateUrl: 'build/pages/login/login.html',
providers: [AuthProvider]
})
export class LoginPage {
static get parameters() {
return [[NavController], [AuthProvider]];
}
constructor(nav, AuthProvider) {
this.nav = nav;
this.authProvider = AuthProvider;
this.form = {};
}
login(form) {
this.authProvider.login(form).then(res => {
alert(JSON.stringify(res));
});
}
}
auth.js (provider)
import {Injectable} from '#angular/core';
import {Http, Headers, RequestOptions} from '#angular/http';
import 'rxjs/add/operator/map';
/*
Generated class for the Auth provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
#Injectable()
export class AuthProvider {
static get parameters(){
return [[Http]]
}
constructor(http) {
this.url = 'http://localhost:3000/api';
this.http = http;
}
login(form) {
return new Promise(resolve => {
this.http.get(this.getUrl)
.map(res => res.json())
.subscribe(data => {
resolve(data);
});
});
}
}
I had the same problem, and was able to resolve it. I was serving my API on localhost:8000. When ionic makes a request to localhost or 127.0.0.1, I think it is blocked. I instead found my computer's IP address and hosted my webserver on 0.0.0.0:8000 and instead of hitting http://localhost:8000/api/my/endpoint I hit http://mycomputerip:8000/api/my/endpoint, and it worked!
You are trying to request empty URL bacause of typo in auth.js login function:
this.http.get(this.getUrl)
this.getUrl is not defined in your code samples. Easy fix:
this.http.get(this.url)

Resources