Can not get Nuxt.js configuration for Axios to work - javascript

I am using Nuxt.js first time now. However I struggle with using the axios module of it somewhat. I like the fact that I can configure the baseUrl in the nuxt.config.js file. I expect. So this is what I did:
// nuxt.config.js
...
axios: {
baseUrl: 'http://localhost:3001',
publicRuntimeConfig: {
axios: {
browserBaseURL: "http://localhost:3004"
}
},
privateRuntimeConfig: {
axios: {
baseURL: "http://localhost:3005"
}
},
},
modules: [
'#nuxtjs/axios',
'#nuxtjs/auth-next',
'#nuxtjs/proxy'
],
...
Here comes my vue components method I declared to use the Nuxt.js axios module (using this.$axios.$get insteand of this.$axios.get). However I am not sure if there is a difference using this.$axios and just $axios. the latter is called a "plugin" according to the documentation. I did not manage to get axios working with only calling $axios - it can't be resolved so I stick with this.$axios.
Anyway here is method code containing the axios get call. As you can see I am omitting the base url https://localhost since I expect it to be prepended through the nuxt.config.js configuration.
updateTeams: function () {
this.$axios.$get('/api/teams')
.then(({data}) => {
this.teams = data
}).catch((error) => {
console.error(error)
})
}
The result is disappointing. The call is still done with http://localhost:3000 instead of one of the others I configured in the nuxt.config.js file. I rechecked the documentation twice but could not find any hint what I am doing wrong.
Request URL: http://localhost:3000/api/teams

Related

Env vars in Svelte - __myapp is not defined

I'm trying to set up env vars on my Svelte app to hide an API key.
I followed the instructions in this article [https://medium.com/dev-cafe/how-to-setup-env-variables-to-your-svelte-js-app-c1579430f032].
Here's the structure of my rollup.config.js
import { config as configDotenv } from 'dotenv';
import replace from '#rollup/plugin-replace';
configDotenv();
export default {
...
plugins: [
replace({
__myapp: JSON.stringify({
env: {
isProd: production,
amplitude_api_key : process.env.amplitude_api_key
}
})
}),
]}
When I try to access the env var by calling: __myapp.env.API_KEY
I get this error: __myapp is not defined
It seems that the nesting is the problem. I was able to get it work using this syntax:
replace({
'process.env.isProd': production,
'process.env.amplitude_api_key': process.env.amplitude_api_key
}),
and then use process.env.isProd in your app. Of course, if you like the __myapp thing, you could use __myapp instead of process on the left side of the replace function in your rollup config.
Even though this thread is solved, I want to point out that your remark "to hide an API key" is invalid because .env on clientside is always parsing right into your sourcecode. So in other words: your api-key is being parsed (and exposed) in the source once you build.

Importing helper functions in Serverless

I want to import a helper function into a Node.js Lambda function in Serverless (AWS). I've tried using Layer functions, as well as a wrapper module for Serverless - but nothing has worked so far.
This is the function I want to use with other Lambda functions - helperFunc.js:
class HelperClass { ... } //a helper class that I want to use in other functions
module.exports = HelperClass
This is one of my Lambda functions. It also serves an API Gateway endpoint - users.js:
"use strict";
const helperClass = require('./helperFunc') //I don't know how to do this
module.exports.get = (event, context, callback) => {
const params = { ... } //DynamoDB Params
// a bunch of code that uses the helper class wrapper
callback(null, {
headers: {
"Access-Control-Allow-Origin" : "*", // Required for CORS support to work
"Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
}, body: JSON.stringify(res), statusCode: 200})
}
};
This is what my serverless.yml currently looks like:
...
getUsers:
handler: src/users.get
events:
- http:
path: users
method: get
authorizer: authFunc
And this what my project directory looks like:
./
serverless.yml
./src
helperFunc.js
users.js
./auth
UPDATE 1: I was finally able to achieve this functionality using Lambda Layers. However, it still feels as if it's not the best way to do this mainly due to the complex directory set-up.
Here's the updated project directory:
./
serverless.yml
./layers/helperFunc/nodejs/node_modules/helperFunc
index.js
./src
users.js
./auth
And here is the updated serverless.yml file:
layers:
helperFunc:
path: layers/helperFunc
...
functions:
getUsers:
handler: src/users.get
layers:
- {Ref: HelperFuncLambdaLayer} # referencing the layer in cf
events:
- http:
path: users
method: get
authorizer: authFunc
The solution is to use serverless-webpack-plugin.

File not found in script

I've installed several libraries using NPM.
You have to load the file to use it there.All installed libraries are under the node_modules
The designation is like this.
<script src="../node_modules/vue/dist/vue.js"></script>
I'm sure it's on the server, I'm sure the URL of the script tag is correct
And I get the following error in the script, even though it is specified like this
login.html:45 GET https://***/node_modules/vue/dist/vue.js net::ERR_ABORTED 404
The JS file I prepared separately is loaded, but the original vue.js is not, so an error is coming back.
That's what we're trying to do with VUE.
I'm going to use Ajax to create an SPA
/* eslint-disable no-console */
const vue = require("vue"); //I added it, but it's still not working.
const axios = require("axios"); //I added it, but it's still not working.
var app = new Vue({
el: "#app",
data: {
url: "https://*****",
user: "",
password: "",
res: ""
},
methods: {
login: function () {
axios.post(this.url, {
user: this.user,
password: this.password
})
.then(function (response) {
this.res = response.data.d;
if (this.res === true) {
//true
} else {
//failed
}
})
.catch(function (error) {
alert('System error');
});
}
}
})
This is how usually use it from node_module
import Vue from 'vue'; // this will check inside node_modules for the file and include
Instead of loading the files through a script tag, use require() in your javascript. For example:
const express = require("express");
const vue = require("vue");
This will work on both the client and on the server.
Why not use a CDN?
This way, the browser will not have to download the Vue file from your server if it has already been cached. Also, you may be able to use the vue.min.js file which will load even faster than the normal Vue dist file...
For example, here is a script from cdnjs.com you could try:
<script
src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"
integrity="sha256-ngFW3UnAN0Tnm76mDuu7uUtYEcG3G5H1+zioJw3t+68="
crossorigin="anonymous"></script>
Try replacing your script tag with this.

How to set proxy for different API server using Nuxt?

So I have 2 applications:
an Adonis API server accessible via http://10.10.120.4:3333
A SSR app using Nuxt.js accessible via http://10.10.120.4:80
The Nuxt.js app is accessible outside using url http://my-website.com. I have axios module with this config
axios: {
baseURL: '0.0.0.0:3333/api',
timeout: 5000
}
Now the problem is, when I am requesting data with asyncData it works, but when the request was made from outside asyncData, say created() for example, it throws an error saying the url http:0.0.0.0:3333 is missing which is true since it's already running in the browser and not in the server.
The first solution that I've tried is to change the baseURL of the axios module to this
axios: {
baseURL: 'http://my-website.com/api',
timeout: 5000
}
But it seems nuxt server can't find it, so I think the solution is to make proxy and installed #nuxtjs/proxy.
And this is my proxy config in nuxt.config.js
{
proxy: {
'/api': 'http://my-website.com:3333',
}
}
and then I just changed my axios baseURL to
http://my-website.com/api
But again it didn't work.
My question is, how do you deal with this kind of scenario? Accessing different server from browser?
When using Proxy in a nuxt project you need to remove baseUrl and set proxy to true as seen below.
axios: {
// Do away with the baseUrl when using proxy
proxy: true
},
proxy: {
// Simple proxy
"/api/": {
target: "https://test.com/",
pathRewrite: { "^/api/": "" }
}
},
when making a call to your endpoint do:
// append /api/ to your endpoints
const data = await $axios.$get('/api/users');
checkout Shealan article

Why is promise.finally in my Vue project not working in Edge?

I'm having tremendous trouble getting my polyfills to work in Edge. I've tried to follow the documentation with various attempts all not working. It seems to be promise.finally specifically that isn't working. This happens in a vuex module so I tried adding vuex to transpileDependencies in vue.config but with no luck.
My babel.config.js:
module.exports = {
presets: [['#vue/cli-plugin-babel/preset', {
useBuiltIns: 'entry',
}]],
};
In my main.js I have the following two imports in the very top:
import 'core-js/stable';
import 'regenerator-runtime/runtime';
My vue.config.js
// eslint-disable-next-line import/no-extraneous-dependencies
const webpack = require('webpack');
const isProd = process.env.NODE_ENV === 'production';
module.exports = {
configureWebpack: {
// Set up all the aliases we use in our app.
plugins: [
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 6,
}),
],
},
css: {
// Enable CSS source maps.
sourceMap: !isProd,
},
transpileDependencies: ['vuex'],
};
Note as mentioned above I have tried both with and without the transpileDepedencies. It says here vue/babel-preset-app that es7.promise.finally is included as a default polyfill
Versions:
Microsoft Edge: 44.18
Microsoft EdgeHTML 18.18362
#vue/cli-plugin-babel": "^4.1.2"
"core-js": "^3.6.4"
"regenerator-runtime": "^0.13.3"
Update 13/02
So I tried to type Promise.prototype on my site in edge and it does appear it is polyfilled:
So currently I'm investigating if some part of my chain (axios/vue axios) does not return a promise. Since it is working in chrome I'm suspecting that a part of the chain is not being polyfilled correctly?
This is my entire chain:
/* VUEX MODULE ACTION */
[a.ALL_CUSTOMERS](context) {
context.commit(m.SET_CUSTOMER_LOADING, true);
CustomerService.getAll()
.then(({ data }) => {
context.commit(m.SET_CUSTOMERS, data);
})
.finally(() => context.commit(m.SET_CUSTOMER_LOADING, false));
},
/* CUSTOMER SERVICE */
import ApiService from '#/common/api.service';
const CustomerService = {
getAll() {
const resource = 'customers/';
return ApiService.get(resource);
},
...
}
/* API SERVICE */
import Vue from 'vue';
import axios from 'axios';
import VueAxios from 'vue-axios';
const ApiService = {
init() {
Vue.use(VueAxios, axios);
let baseUrl = process.env.VUE_APP_APIURL;
Vue.axios.defaults.baseURL = baseUrl;
},
setHeader() {
Vue.axios.defaults.headers.common.Authorization = `Bearer ${getToken()}`;
},
get(resource) {
this.setHeader();
return Vue.axios.get(`${resource}`);
},
...
}
I have ever faced that issue before.
Only finally didn't work on Edge.
I updated finally like below VVV and it worked.
This should handle the propagation of the thenable's species in addition to the behaviors detailed below:
Promise.prototype.finally = Promise.prototype.finally || {
finally (fn) {
const onFinally = value => Promise.resolve(fn()).then(() => value);
return this.then(
result => onFinally(result),
reason => onFinally(Promise.reject(reason))
);
}
}.finally;
This implementation is based on the documented behavior of finally() and depends on then() being compliant to the specification:
A finally callback will not receive any argument, since there's no
reliable means of determining if the promise was fulfilled or
rejected. This use case is for precisely when you do not care about
the rejection reason, or the fulfillment value, and so there's no need
to provide it.
Unlike Promise.resolve(2).then(() => {}, () => {}) (which will be
resolved with undefined), Promise.resolve(2).finally(() => {}) will be
resolved with 2.
Similarly, unlike Promise.reject(3).then(() => {}, () => {}) (which
will be fulfilled with undefined), Promise.reject(3).finally(() => {})
will be rejected with 3.
Note: A throw (or returning a rejected promise) in the finally
callback will reject the new promise with the rejection reason
specified when calling throw().
This is a known issue in core-js.
In theory, Edge provides a Promise polyfill for finally, but perhaps something is going on with the feature detection or your browserlist and you need to provide a polyfill :shrug:
I would delete both the Vue babel plugin and core-js from your project and then npm install them fresh.
npm install #vue/cli-plugin-babel --save-dev
npm install core-js --save
Also, make sure you're using core-js#3 via your config (babel.config.js) here
Lastly, there's a few Github issues talking about polyfills + Promises with regards to the other 3rd party libraries executed in your vuex store. Add all three of those libraries (axios, vue-axios, vuex) to your transpileDependencies section. If that fixes it, start removing the dependencies to see if they're needed.
Try adding a .browserslistrc file to your projects root with the following content:
> 1%
last 2 versions
See https://github.com/browserslist/browserslist#best-practices information on last versions configuration.
If this does not resolve missing poly-fill, try disabling the plugin you are using that limits the number of chunks in order to ensure that this is not causing any poly-fills to be omitted.
plugins: [
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 6,
}),
],

Categories