I don't understand these errors when I export as production npm run build , but when I test npm run dev it works just fine. I use getStaticProps and getStaticPath fetch from an API route.
First when I npm run build
FetchError: invalid json response body at https://main-website-next.vercel.app/api/products reason: Unexpected token T in JSON at position
0
at D:\zummon\Main Website\main-website-next\node_modules\node-fetch\lib\index.js:272:32
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async getStaticPaths (D:\zummon\Main Website\main-website-next\.next\server\pages\product\[slug].js:1324:18)
at async buildStaticPaths (D:\zummon\Main Website\main-website-next\node_modules\next\dist\build\utils.js:16:80)
at async D:\zummon\Main Website\main-website-next\node_modules\next\dist\build\utils.js:26:612
at async D:\zummon\Main Website\main-website-next\node_modules\next\dist\build\tracer.js:1:1441 {
type: 'invalid-json'
}
\pages\product\[slug]
import { assetPrefix } from '../../next.config'
export default function Page(){...}
export const getStaticProps = async ({ params: { slug }, locale }) => {
const res = await fetch(`${assetPrefix}/api/products/${slug}`)
const result = await res.json()
const data = result.filter(item => item.locale === locale)[0]
const { title, keywords, description } = data
return {
props: {
data,
description,
keywords,
title
}
}
}
export const getStaticPaths = async () => {
const res = await fetch(`${assetPrefix}/api/products`)
const result = await res.json()
const paths = result.map(({ slug, locale }) => ({ params: { slug: slug }, locale }))
return {
fallback: true,
paths,
}
}
next.config.js
const isProd = process.env.NODE_ENV === 'production'
module.exports = {
assetPrefix: isProd ? 'https://main-website-next.vercel.app' : 'http://localhost:3000',
i18n: {
localeDetection: false,
locales: ['en', 'th'],
defaultLocale: 'en',
}
}
API routes
// pages/api/products/index.js
import data from '../../../data/products'
export default (req, res) => {
res.status(200).json(data)
}
// pages/api/products/[slug].js
import db from '../../../data/products'
export default ({ query: { slug } }, res) => {
const data = db.filter(item => item.slug === slug)
if (data.length > 0) {
res.status(200).json(data)
} else {
res.status(404).json({ message: `${slug} not found` })
}
}
// ../../../data/products (data source)
module.exports = [
{ locale: "en", slug: "google-sheets-combine-your-cashflow",
title: "Combine your cashflow",
keywords: ["Google Sheets","accounting"],
description: "...",
},
...
]
Second when I remove the production domain, I run npm run build but still get the error like
TypeError: Only absolute URLs are supported
at getNodeRequestOptions (D:\zummon\Main Website\main-website-next\node_modules\node-fetch\lib\index.js:1305:9)
at D:\zummon\Main Website\main-website-next\node_modules\node-fetch\lib\index.js:1410:19
at new Promise (<anonymous>)
at fetch (D:\zummon\Main Website\main-website-next\node_modules\node-fetch\lib\index.js:1407:9)
at getStaticPaths (D:\zummon\Main Website\main-website-next\.next\server\pages\[slug].js:938:21)
at buildStaticPaths (D:\zummon\Main Website\main-website-next\node_modules\next\dist\build\utils.js:16:86)
at D:\zummon\Main Website\main-website-next\node_modules\next\dist\build\utils.js:26:618
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async D:\zummon\Main Website\main-website-next\node_modules\next\dist\build\tracer.js:1:1441 {
type: 'TypeError'
}
My next.config.js after remove
const isProd = process.env.NODE_ENV === 'production'
module.exports = { //remove
assetPrefix: isProd ? '' : 'http://localhost:3000',
i18n: {
localeDetection: false,
locales: ['en', 'th'],
defaultLocale: 'en',
}
}
My package.json when I npm run build script
{
"name": "main-website-next",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build && next export",
"start": "next start"
},
"dependencies": {
"next": "10.0.6",
"react": "17.0.1",
"react-dom": "17.0.1"
}
}
You should not call an internal API route inside getStaticProps. Instead, you can safely use your API logic directly in getStaticProps/getStaticPaths. These only happen server-side so you can write server-side code directly.
As getStaticProps runs only on the server-side, it will never run on
the client-side. It won’t even be included in the JS bundle for the
browser, so you can write direct database queries without them being
sent to browsers.
This means that instead of fetching an API route from
getStaticProps (that itself fetches data from an external source),
you can write the server-side code directly in getStaticProps.
Furthermore, your API routes are not available during build-time, as the server has not been started at that point.
Here's a small refactor of your code to address the issue.
// /pages/product/[slug]
import db from '../../../data/products'
// Remaining code..
export const getStaticProps = async ({ params: { slug }, locale }) => {
const result = db.filter(item => item.slug === slug)
const data = result.filter(item => item.locale === locale)[0]
const { title, keywords, description } = data
return {
props: {
data,
description,
keywords,
title
}
}
}
export const getStaticPaths = async () => {
const paths = db.map(({ slug, locale }) => ({ params: { slug: slug }, locale }))
return {
fallback: true,
paths,
}
}
Related
I have been trying to figure out how to make the switcher or language selector work from the frontend part of the website. Also my first time working with SSR, so I am not sure about the communication in between. So far what I handled and works well, the inclusion for the translation rendering is working, also when i manually change the language for testing purpose.
I have been reading the documentation, but there is not specific tutorial about how to handle this, more than the function "changeLanguage" and some solutions I found are older as 5 years and involves, deprecated version and some kind of extra library to handled some template views, and I don't know if if this actually is still feasible. However inside the repository from i18next-http-middleware, there is an example that basically does kind what I want. So can be found under the "basic-pug" folder. The difference is that it is used "Pug" as a template engine, which I don't think it should affect or make any difference. so I used exactly the same configuration as the example, which i downloaded and tested and it was working, so it supposed enabled a cookie, and then on the url can pass the cookie as a param, with the locale, and it supposed to work, however not working with in my project, and I also wondering if it possible to have "/de/" instead "/?lang=de", example www.myweb.com/de/about and not www.myweb.com/about/?lang=de, because that's not exactly what I was imagining, and also no clear how to handled when u have nested or several routes.
In general, I was wondering how to use the "changelanguage" function in the frontend side, so I have, for example, something like:
<div>
<div onclick="Changelanguage("de")"> Deutsch</div>
<div onclick="Changelanguage("en")"> English</div>
</div>
Because by declaring the function just like in the views, on a script tag, I the changelanguage is not a function, because there is no communication between both.
Please find below my configuration:
Json file:
{
"name": "project",
"version": "0.0.0",
"private": true,
"author": "project",
"main": "dist/index.js",
"scripts": {
"start": "node dist/index.js",
"dev": "nodemon src/index.js --exec \"node -r dotenv/config -r #babel/register\"",
"clean": "rimraf dist",
"build": "npm run clean && mkdir -p dist && babel src -s -D -d dist",
"postinstall": "npm run build"
},
"dependencies": {
"#babel/cli": "^7.18.9",
"#babel/core": "^7.18.9",
"#babel/plugin-proposal-class-properties": "^7.18.6",
"#babel/plugin-proposal-object-rest-spread": "^7.18.9",
"#babel/preset-env": "^7.18.9",
"body-parser": "^1.19.0",
"ejs": "^3.1.8",
"express": "^4.18.1",
"graphql": "^16.5.0",
"graphql-request": "^4.3.0",
"i18next": "^21.9.1",
"i18next-fs-backend": "^1.1.5",
"i18next-http-middleware": "^3.2.1",
"locomotive-scroll": "^4.1.4",
"morgan": "^1.10.0",
"node-sass-middleware": "^1.0.1",
"rimraf": "^3.0.0"
},
"devDependencies": {
"#babel/register": "^7.18.9",
"dotenv": "^16.0.1",
"nodemon": "^2.0.19"
},
"babel": {
"presets": [
[
"#babel/preset-env",
{
"targets": {
"node": "current"
}
}
]
],
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-proposal-object-rest-spread"
]
}
}
My routes file js
import { GraphQLClient
} from "graphql-request";
import { Router
} from "express";
import * as queries from "./queries";
import i18next from "i18next";
const routes = Router();
export function request({ query, variables, preview, includeDrafts
}) {
// ...some headers and client configs
};
return client.request(query, variables);
}
let generalInfo = null;
const getData = async (options) => {
options.page = options.page ? options.page : "";
if (!generalInfo) {
generalInfo = await request({
query: queries.getGeneralInfo,
variables: {
locale: options.lang
}
});
}
let q = queries.getPage(options.page);
let data = await request({
query: q,
variables: {
locale: options.lang
}
});
data = Object.assign(data, generalInfo);
return data;
};
const getCase = async (slug, lang) => {
if (!generalInfo) {
generalInfo = await request({
query: queries.getGeneralInfo,
variables: {
locale: lang
}
});
}
slug = slug ? slug : "";
let q = queries.getCase;
let data = await request({
query: q,
variables: {
locale: lang
}
});
data = Object.assign(data, generalInfo);
const filter = data.allCases.filter((n) => n.slug == slug)
return filter;
};
const getInnerPage = async (slug, lang) => {
if (!generalInfo) {
generalInfo = await request({
query: queries.getGeneralInfo,
variables: {
locale: lang
}
});
}
slug = slug ? slug : "";
let q = queries.getInner;
let data = await request({
query: q,
variables: {
locale: lang
}
});
data = Object.assign(data, generalInfo);
const filter = data.allPages.filter((n) => n.slug == slug);
return filter;
};
routes.get("/cases/:slug", (req, res) => {
let slug = req.params.slug;
getCase(slug, req.locale).then(filter => {
if (filter.length) {
res.render("case",
{ title: filter.project_title, filter, t: i18next.t
});
} else {
res.render("404");
}
}).catch(e => {
console.error(e);
});
});
routes.get("/page/:slug", (req, res) => {
let slug = req.params.slug;
getInnerPage(slug, req.locale).then(filter => {
if (filter.length) {
res.render("page",
{ title: filter[
0
].titlePage, filter, t: i18next.t
});
} else {
res.render("404");
}
}).catch(e => {
console.error(e);
});
});
routes.get("/", (req, res) => {
let options = { 'lang': req.locale, 'page': ""
}
//console.log(req.locale + " locale selected");
getData(options).then(data => {
res.render("home",
{ title: "Home", data, t: i18next.t
});
}).catch(e => {
console.error(e);
});
});
export default routes;
My index js
import express from "express";
import path from "path";
import logger from "morgan";
import bodyParser from "body-parser";
import routes from "./routes";
import sassMiddleware from "node-sass-middleware";
import i18next from "i18next";
import i18nextBackend from "i18next-fs-backend";
import i18nextMiddleware from "i18next-http-middleware";
const { PORT = 5050 } = process.env;
const app = express();
i18next.use(i18nextBackend)
.use(i18nextMiddleware.LanguageDetector)
.init({
//lng: 'de',
debug: true,
fallbackLng: 'en',
preload: ['de', 'en'],
backend: {
loadPath: './locales/{{lng}}/translation.json'
},
detection: {
order: ['querystring', 'cookie'],
caches: ['cookie'],
lookupQuerystring: 'lang',
lookupCookie: 'lang',
ignoreCase: true,
cookieSecure: false
},
})
app.use(i18nextMiddleware.handle(i18next));
//i18next.changeLanguage('de');
app.set("views", path.join(__dirname, "../views"));
app.set("view engine", "ejs");
app.use(logger("dev"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.locals = { config: { whatever: 'this is' } };
app.use(
sassMiddleware({
src: path.join(__dirname, "../public/scss"),
dest: path.join(__dirname, "../public"),
indentedSyntax: false,
sourceMap: false
})
);
app.use(express.static(path.join(__dirname, "../public")));
app.use("/", routes);
app.use(function (req, res) {
res.status(404).render('404.ejs');
});
app.use(function (req, res) {
res.status(500).render('500.ejs');
});
app.listen(PORT, () => {
console.log(`Listening on port ${PORT}`);
});
export default app;
Thank you in advance for any help, I think I am mainly struggling because I use to work on client side, but still learning about SSR.
You should be able to define the language also in the route, like described here: https://github.com/i18next/i18next-http-middleware#language-detection
Define the 'path' in the detection options: order: ['path', /*'session', */ 'querystring', 'cookie', 'header'],
Regarding the language change. You probably just need to navigate to the route with the appropriate language.
I have the same issue than this post: Why does vitest mock not catch my axios get-requests?
I would like to test my vuex store on vuejs and it works for getters etc but not for actions part with axios get request.
I don't know if it's a good practice to test vuex store than the component in Vue ?
But I guess I need to test both, right ?
a project https://stackblitz.com/edit/vitest-dev-vitest-nyks4u?file=test%2Ftag.spec.js
my js file to test tag.js
import axios from "axios";
const actions = {
async fetchTags({ commit }) {
try {
const response = await axios.get(
CONST_CONFIG.VUE_APP_URLAPI + "tag?OrderBy=id&Skip=0&Take=100"
);
commit("setTags", response.data);
} catch (error) {
console.log(error);
return;
}
},
};
export default {
state,
getters,
actions,
mutations,
};
then my test (tag.spec.js)
import { expect } from "chai";
import { vi } from "vitest";
import axios from "axios";
vi.mock("axios", () => {
return {
default: {
get: vi.fn(),
},
};
});
describe("tag", () => {
test("actions - fetchTags", async () => {
const users = [
{ id: 1, name: "John" },
{ id: 2, name: "Andrew" },
];
axios.get.mockImplementation(() => Promise.resolve({ data: users }));
axios.get.mockResolvedValueOnce(users);
const commit = vi.fn();
await tag.actions.fetchTags({ commit });
expect(axios.get).toHaveBeenCalledTimes(1);
expect(commit).toHaveBeenCalledTimes(1);
});
});
It looks like some other peolpe have the same issues https://github.com/vitest-dev/vitest/issues/1274 but it's still not working.
I try with .ts too but I have exactly the same mistake:
FAIL tests/unit/store/apiObject/tag.spec.js > tag > actions - fetchTags
AssertionError: expected "spy" to be called 1 times
❯ tests/unit/store/apiObject/tag.spec.js:64:24
62| await tag.actions.fetchTags({ commit });
63|
64| expect(axios.get).toHaveBeenCalledTimes(1);
| ^
65| expect(commit).toHaveBeenCalledTimes(1);
66| });
Expected "1"
Received "0"
Thanks a lot for your help.
I finally found the mistake, it was on my vitest.config.ts file, I have to add my global config varaible for my api: import { config } from "#vue/test-utils";
import { defineConfig } from "vitest/config";
import { resolve } from "path";
var configApi = require("./public/config.js");
const { createVuePlugin } = require("vite-plugin-vue2");
const r = (p: string) => resolve(__dirname, p);
export default defineConfig({
test: {
globals: true,
environment: "jsdom",
},
define: {
CONST_CONFIG: configApi,
},
plugins: [createVuePlugin()],
resolve: {
alias: {
"#": r("."),
"~": r("."),
},
// alias: {
// "#": fileURLToPath(new URL("./src", import.meta.url)),
// },
},
});
I'm trying to make a smart request in nuxt with nuxt-apollo-module in order to grab my routes for the nuxt-sitemaps-module (so I can create my sitemap with them).
I need to make this request from within nuxt.config.js file. I have tried this way with no luck (as app doesn't exist in this context). What would be the right way to do this?
Thanks in advance!
The relevant part of my nuxt.config.js
import gql from 'graphql-tag'
module.exports = {
modules: [
'#nuxtjs/apollo',
'#nuxtjs/sitemap'
],
apollo: {
clientConfigs: {
default: {
httpEndpoint: 'https://example.com/graphql'
}
}
},
sitemap: {
path: '/sitemap.xml',
hostname: 'https://example.com/',
generate: true,
cacheTime: 86400,
trailingSlash: true,
routes: async ({ app }) => {
const myRoutes = ['/one-random-path/']
let client = app.apolloProvider.defaultClient
let myProductsQuery = gql`query {
products {
slug
}
}`
let myBrandsQuery = gql`query {
brands {
slug
}
}`
const myProducts = await client.query({ query: myProductsQuery })
const myBrands = await client.query({ query: myBrandsQuery })
return [myRoutes, ...myProducts, ...myBrands]
}
}
}
I was able to generate it this way, but I'm sure there is a better way.
yarn add node-fetch apollo-boost
sitemap: {
routes: async () => {
const routes = []
const fetch = require("node-fetch")
const { gql } = require("apollo-boost")
const ApolloBoost = require("apollo-boost")
const ApolloClient = ApolloBoost.default
const client = new ApolloClient({
fetch: fetch,
uri: YOUR_API_ENDPOINT,
})
const fetchUsers = gql`
query {
users {
id
}
}
`
const users = await client
.query({
query: fetchUsers,
})
.then((res) => res.data.users)
users.forEach((user) => {
routes.push({
route: `/${user.id}`,
})
})
return routes
},
},
I gave up using Apollo. It was easier to use Axios. Moreover, no nneds to configure #nuxtjs/sitemap :
import axios from 'axios'
sitemap: {
hostname: URL_SITE,
gzip: true,
},
routes() {
return axios({
url: ENDPOINT,
method: 'post',
data: {
query: `
query GET_POSTS {
posts {
nodes {
slug
}
}
}
`,
},
}).then((result) => {
return result.data.data.posts.nodes.map((post) => {
return '/blog/' + post.slug
})
})
}
This was how I was able to do it with authentication. Got round to it by following the documentation here which had a Vue example: https://www.apollographql.com/docs/react/networking/authentication/
Might be a cleaner way to do it with apollo-boost if you can also use auth?
import fetch from 'node-fetch'
import { ApolloClient } from 'apollo-client'
import { HttpLink } from 'apollo-link-http'
import { ApolloLink, concat } from 'apollo-link'
import { InMemoryCache } from 'apollo-cache-inmemory'
import globalQuery from './apollo/queries/global.js'
const httpLink = new HttpLink({ uri: process.env.SCHEMA_URL, fetch })
const authMiddleware = new ApolloLink((operation, forward) => {
// add the authorization to the headers
const token = process.env.STRAPI_API_TOKEN
operation.setContext({
headers: {
authorization: token ? `Bearer ${token}` : 'Bearer',
},
})
return forward(operation)
})
export const apolloClient = new ApolloClient({
link: concat(authMiddleware, httpLink),
cache: new InMemoryCache(),
})
export default async () => {
let global = null
const globalResponse = await apolloClient.query({ query: globalQuery })
if (globalResponse?.data?.global?.data) {
global = globalResponse.data.global.data.attributes
}
console.log('globals:::', global)
}
I have this error with eslint. I am working with vue/vuex. This is my stacktrace:
> Module build failed (from ./node_modules/eslint-loader/index.js):
> Error: No ESLint configuration found in
> /Users/name/Desktop/blognewtonmcvue/store.
> at CascadingConfigArrayFactory._finalizeConfigArray (/Users/anme/Desktop/blognewtonmcvue/mevnexample/node_modules/eslint/lib/cli-engine/cascading-config-array-factory.js:432:19)
> at CascadingConfigArrayFactory.getConfigArrayForFile (/Users/name/Desktop/blognewtonmcvue/mevnexample/node_modules/eslint/lib/cli-engine/cascading-config-array-factory.js:271:21)
> at CLIEngine.isPathIgnored (/Users/name/Desktop/blognewtonmcvue/mevnexample/node_modules/eslint/lib/cli-engine/cli-engine.js:951:18)
> at CLIEngine.executeOnText (/Users/name/Desktop/blognewtonmcvue/mevnexample/node_modules/eslint/lib/cli-engine/cli-engine.js:868:38)
> at lint (/Users/name/Desktop/blognewtonmcvue/mevnexample/node_modules/eslint-loader/index.js:278:17)
> at transform (/Users/name/Desktop/blognewtonmcvue/mevnexample/node_modules/eslint-loader/index.js:252:18)
> at /Users/name/Desktop/blognewtonmcvue/mevnexample/node_modules/loader-fs-cache/index.js:127:18
> at ReadFileContext.callback (/Users/name/Desktop/blognewtonmcvue/mevnexample/node_modules/loader-fs-cache/index.js:31:14)
> at FSReqCallback.readFileAfterOpen [as oncomplete] (node:fs:273:13)
One of the solutions I tried was to use
eslint --init
and then i got this file:
eslintrc.js
module.exports = {
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:vue/essential"
],
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"vue"
],
"rules": {
}
};
But the error points to my store files posts.js and store.js
post.js
import axios from "axios";
import vuex from "vuex";
const state = {
posts: [],
};
const getters = {
allPosts: (state) => state.Posts,
};
const actions = {
//an action: makes a request, gets a response and calls a mutation
async fetchPosts({ commit }) {
// commit - to call the mutation
const response = await axios.get("http://localhost:4000/posts");
commit("setPosts", response.data);
},
async addPosts({ commit }, title) {
const response = await axios.post("http://localhost:4000/posts/add", {
title,
completed: false,
});
commit("newPost", response.data);
},
async deletePosts({ commit }, id) {
await axios.delete(`http://localhost:4000/posts/delete/${id}`);
commit("removePosts", id);
},
async filterPosts({ commit }, e) {
//Get selected number
// const limit = parseInt(e.target.options[e.target.options.selectedIndex].innerText);
const limit = e.target.value;
const response = await axios.get(`http://localhost:4000/posts`);
commit("setPosts", response.data);
},
async updatePosts({ commit }, updatePosts) {
const response = await axios.put(
`http://localhost:4000/posts/update/${this.$route.params.id}`,
updatePosts
);
console.log(response.data);
commit("updatePosts", response.data);
},
};
const mutations = {
setPost: (state, posts) => (state.posts = posts),
newPost: (state, posts) => state.posts.unshift(posts),
removePost: (state, id) =>
(state.posts = state.posts.filter((posts) => posts.id !== id)),
updatePosts: (state, updPosts) => {
const index = state.Posts.findIndex((posts) => posts.id === updPosts.id);
if (index !== -1) {
state.posts.splice(index, 1, updPosts);
}
},
};
export default {
state,
getters,
actions,
mutations,
};
//this is a boilerplate for vuex module
This is my other file. Both store.js and post.js files are in the directory/map "store"
store.js
import Vuex from "vuex";
import Vue from "vue";
import store from "./post";
//load Vuex
Vue.use(Vuex);
//create store
export default new Vuex.Store({
modules: {
post,
},
});
I have babel.config.js
.eslintrc.js in my project
I solved this by this steps.
npm uninstall eslint (because i had the wrong version)
npm install eslint#7.11.0(did this because it supported es2021)
If this steps do not work try to clone your project again from github
I'm trying to write my first unit test for a VueJS component that grabs some data from an API endpoint when it renders:
My VueJS component:
import axios from 'axios';
export default {
props: {
userIndexUrl: {
required: true
}
},
data() {
userList: [],
tableIsLoading: true
},
created() {
const url = this.userIndexUrl;
axios.get(url)
.then(response => {
this.userList = response.data.data;
this.tableIsLoading = false;
})
},
}
and my test:
import { mount } from 'vue-test-utils'
import moxios from 'moxios'
import UsersAddRemove from 'users_add_remove.vue'
describe('UsersAddRemove', () => {
const PROPS_DATA = {
userIndexUrl: '/users.json'
}
beforeEach(() => {
moxios.install();
moxios.stubRequest('/users1.json', {
status: 200,
response: {
"count": 1,
"data": [
{ "id" : 1,
"email" : "brayan#schaeferkshlerin.net",
"first_name" : "Kenneth",
"last_name" : "Connelly"
}
]
}
});
});
afterEach(() => {
moxios.uninstall();
});
it('loads users from remote JSON endpoint and renders table', () => {
const wrapper = mount(UsersAddRemove, { propsData: PROPS_DATA });
moxios.wait(() => {
expect(wrapper.html()).toContain('<td class="">brayan#schaeferkshlerin1.net</td>');
done();
});
});
});
So what I expect to happen is the component gets instantiated, after which it does an API call, which is caught by Moxios, after which it should execute moxios.wait, which isn't happening. The tests seem to ignore moxios.wait, and it passes successfully even when it shouldn't.
What am I missing here?
Try adding the done as argument:
it('loads users from remote JSON endpoint and renders table', (done) => {
// -----------------------------------------------------------^^^^^^
const wrapper = mount(UsersAddRemove, { propsData: PROPS_DATA });
moxios.wait(() => {
expect(wrapper.html()).toContain('<td class="">brayan#schaeferkshlerin1.net</td>');
done();
});
});
Waiting for the Ajax
Change as follows:
// remove the stubRequest of beforeEach()
beforeEach(() => {
moxios.install();
});
// afterEach stays the same
it('loads users from remote JSON endpoint and renders table', (done) => {
const wrapper = mount(UsersAddRemove, { propsData: PROPS_DATA });
moxios.wait(() => {
let request = moxios.requests.mostRecent();
request.respondWith({
status: 200,
response: {
"count": 1,
"data": [{
"id": 1,
"email": "brayan#schaeferkshlerin.net",
"first_name": "Kenneth",
"last_name": "Connelly"
}]
}
}).then(function() {
expect(wrapper.html()).toContain('<td class="">brayan#schaeferkshlerin1.net</td>');
done();
});
});
});