Modifying a fetch request for vuejs - vue.js

I am new to using a fetch request with vue. I have a fetch request that works great, but want to modify the properties to use the data that is found in the model. Right now it hardcodes everything in it, but need some properties to be dynamic for instance like if the title comes from an input field or if the referral code comes from a cookie.
new Vue({
el: "#app",
data: {
title:"jjj",
kol_referrer:localStorage.getItem('shell'),,
url:"https%3A%2F%2Fshared%2Fdoggo%2520(2).png"
},
methods: {
submit: function(){
fetch("", {
"headers": {
"accept": "*/*",
"accept-language": "en-US,en;q=0.9",
"content-type": "application/x-www-form-urlencoded",
"sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"96\", \"Google Chrome\";v=\"96\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"macOS\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin"
},
"referrer": "",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": "title=jjj&url=https%3A%2F%2Fshared%2Fdoggo%2520(2).png&opensInNewWindow=1&isXhr=true&requestId=2&kol_referrer=LxOfRIA4TdeWTYA0rT96AGz",
"method": "POST",
"mode": "cors",
"credentials": "include"
});
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Todos:</h2>
<button v-on:click="submit">Click</button>
</div>

Simply use templates litterals with backticks :
submit: function() {
let myTitle = "myTitle"
let myKolReferrer = "foo"
fetch("", {
"headers": {
"accept": "*/*",
"accept-language": "en-US,en;q=0.9",
"content-type": "application/x-www-form-urlencoded",
"sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"96\", \"Google Chrome\";v=\"96\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"macOS\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin"
},
"referrer": "",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": `title=${myTitle}&kol_referrer=${myKolReferrer}`,
"method": "POST",
"mode": "cors",
"credentials": "include"
});
}

Related

VueJS and Axios handle errors properly

I am trying to raise an error during the login ... but weird thing is -> it does not work as I would expect it to ...
I am having this simple auth.service.js
class AuthService {
async login(params) {
try {
const user = (await axios.post('/authentication', { ...params })).data;
return true;
} catch (err) {
console.log(err);
throw new Error(err);
}
}
}
export default new AuthService();
The "err" has the full axios error object (as shown below)
{
"message": "Request failed with status code 401",
"name": "AxiosError",
"stack": "AxiosError: Request failed with status code 401\n at settle (http://localhost:3000/node_modules/.vite/deps/axios.js?v=430fef65:1124:12)\n at XMLHttpRequest.onloadend (http://localhost:3000/node_modules/.vite/deps/axios.js?v=430fef65:1335:7)",
"config": {
"transitional": {
"silentJSONParsing": true,
"forcedJSONParsing": true,
"clarifyTimeoutError": false
},
"adapter": [
"xhr",
"http"
],
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1,
"env": {},
"headers": {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json"
},
"baseURL": "http://localhost:3030",
"method": "post",
"url": "/authentication",
"data": "{\"username\":\"admin\",\"password\":\"admin\",\"strategy\":\"local\"}"
},
"code": "ERR_BAD_REQUEST",
"status": 401
}
what is weird is, that when I use that in my login method .. I am getting just the name and message values ... nothing else :(
methods: {
async login() {
const payload = { username: this.username, password: this.password, strategy: 'local' };
AuthService.login(payload)
.then(() => {
this.$router.push({ name: 'home' });
this.loading = false;
})
.catch(error => {
console.log(error); // THIS DOES NOT SHOW THE ENTIRE OBJECT WITH ALL KEYS
this.loading = false;
});
},
any idea why?

How i can store an API body response and use it in other test on cypress?

I have this code to store response.body.address_id and use it in the next test but not working.
this is my hole code (two tests) :
`it('Create Address',function(){
return cy.request({
method:'POST',
url: `${Cypress.env('API_URL')}/address/api/v1/addresses`,
headers:{
Authorization : `${Cypress.env('access_token')}`,
"Content-Type": 'application/json',
},
body:{
"address_name": "Home",
"locality_area_street": "16th district",
"city": "DAKAR",
"country": "SENEGAL",
}}
).then((response)=>{
expect(response.status).to.eq(201)
Cypress.env('address_id', response.body.address_id);
})
})
it('Add Address',function(){
cy.request({
method:'PUT',
url: 'https://api/v1/cart/address',
headers:{
Authorization : `Bearer ${Cypress.env('access_token')}`,
"Content-Type": 'application/json',
},
body:{
"addressType": "BILLING",
"id": `${Cypress.env('address_id')}`
}}
).then((response)=>{
cy.log(Cypress.env('address_id'));
expect(response.status).to.eq(200)
})
})
})`
Can somme one help me to find a solution ?
You probably shouldn't use the Cypress.env for this,
Try this:
it("Create Address", function () {
return cy
.request({
method: "POST",
url: `${Cypress.env("API_URL")}/address/api/v1/addresses`,
headers: {
Authorization: `${Cypress.env("access_token")}`,
"Content-Type": "application/json",
},
body: {
address_name: "Home",
locality_area_street: "16th district",
city: "DAKAR",
country: "SENEGAL",
},
})
.then((response) => {
expect(response.status).to.eq(201);
Cypress.env("address_id", response.body.address_id);
this.address_id = response.body.address_id;
});
});
it("Add Address", function () {
cy.request({
method: "PUT",
url: "https://api/v1/cart/address",
headers: {
Authorization: `Bearer ${Cypress.env("access_token")}`,
"Content-Type": "application/json",
},
body: {
addressType: "BILLING",
id: this.address_id,
},
}).then((response) => {
cy.log(this.address_id);
expect(response.status).to.eq(200);
});
});

How do I login a user using nuxt auth's loginWith() function?

I am creating an application that uses nuxt as frontend and an expressjs api as backend.
JWT token authentication is working in backend and I am now trying to register a user from the frontend and log him in using Nuxt auth's loginWith().
When I try to register a user, auth.loggedIn and auth.user are both equal to false. I don't understand what is going wrong as I'd expect auth.loggedIn to be true and auth.user to have the value returned by my '/api/me' api route.
nuxt.config.js
auth: {
strategies: {
local: {
endpoints: {
login: { url: 'login', method: 'post', propertyName: 'data.token' },
user: { url: 'me', method: 'post', propertyName: 'data.user'},
logout: false
}
}
}
},
register.vue
<template>
<v-app>
<h2>Register</h2>
<form method="post" #submit.prevent="register">
<v-container fluid>
<v-row>
<v-col cols="12" sm="6">
<v-text-field v-model="username" label="username" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field v-model="email" label="email" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field v-model="password" label="password" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field v-model="matchPassword" label="password" />
</v-col>
</v-row>
</v-container>
<v-btn type="submit">Register</v-btn>
</form>
<div style="margin-top: 20px">
Already got an account ? <nuxt-link to="/login">Login</nuxt-link>
</div>
</v-app>
</template>
<script>
export default {
name:"registerComponent",
data () {
return {
username: '',
email: '',
password: '',
matchPassword: '',
error: null
}
},
methods: {
async register () {
try {
const registerReponse = await this.$axios.post('register', {
username: this.username,
email: this.email,
password: this.password
})
const loginResponse = await this.$auth.loginWith('local', {
data: {
email: this.email,
password: this.password
},
})
console.log(registerReponse, loginResponse)
// this.$router.push('/')
} catch (e) {
this.error = e.response.data.message
}
},
},
}
</script>
Here's the output of the console.log() above when registering a user :
{
"data": {
"message": "User created "
},
"status": 201,
"statusText": "Created",
"headers": {
"content-length": "27",
"content-type": "application/json; charset=utf-8"
},
"config": {
"url": "register",
"method": "post",
"data": "{\"username\":\"oi\",\"email\":\"oiu#oiu.oiu\",\"password\":\"poiupoiu\"}",
"headers": {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json"
},
"baseURL": "http://localhost:3002/api",
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1,
"transitional": {
"silentJSONParsing": true,
"forcedJSONParsing": true,
"clarifyTimeoutError": false
}
},
"request": {}
},
{
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MjYsInVzZXJfbmFtZSI6Im9pdSIsImlhdCI6MTY2NDk2MDc1NSwiZXhwIjoxNjY0OTcxNTU1fQ.goay796jUdmi-NYjSloDdeK6besuz8swJcMslDmklZU"
},
"status": 200,
"statusText": "OK",
"headers": {
"content-length": "181",
"content-type": "application/json; charset=utf-8"
},
"config": {
"url": "login",
"method": "post",
"data": "{\"email\":\"oiu#oiu.oiu\",\"password\":\"poiupoiu\"}",
"headers": {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json"
},
"baseURL": "http://localhost:3002/api",
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1,
"transitional": {
"silentJSONParsing": true,
"forcedJSONParsing": true,
"clarifyTimeoutError": false
},
"propertyName": "data.token"
},
"request": {}
}
Express app
You can see above the output of the /api/register and /api/login routes.
Here's the /api/me route (it just returns a hard-coded username for now) :
app.post('/api/me', authenticateJWT, (req, res) => {
client.query('SELECT user_name from user_account where id = $1', ['1'], (error, results) => {
res.json( {user: { username: results.rows[0].user_name }} )
})
})
Edit
Here's a screenshot of the vue devtool after attempting to register a user
I've found the issue : I needed to set the token property in nuxt.config.js.
Nuxt.config.js
auth: {
strategies: {
local: {
token: {
property: 'data.accessToken',
global: true
},
endpoints: {
login: { url: 'login', method: 'post', propertyName: 'data.token' },
user: { url: 'me', method: 'post', propertyName: 'data.user'},
logout: false
}
}
}
},
The 'user' state is now correctly set to the response from the backend and 'loggedIn' is set to True.

Axios returns a string instead of JSON (vue.js)

I don't understand why but axios is returning a string instead of json. Can someone explain me why ?
<template>
<div class="app">
<Header/>
<h1>{{services}}</h1>
<Services v-bind:services="services"></Services>
</div>
</template>
<script>
import Header from "./components/Header.vue";
import Services from "#/components/Service";
import axios from 'axios';
export default {
name: 'App',
components: {
Services,
Header,
},
data() {
return {
services: [],
}
},
created() {
const instance = axios.create({
baseURL: 'http://localhost:3000/api',
timeout: 1000,
headers: {'Authorization': 'Bearer ' + 'mysecretcode'}
});
instance.get('/service')
.then(response => {
this.services = response.data;
console.log(response.data);
})
.catch(e => {
this.errors.push(e)
})
},
}
</script>
<style>
</style>
I saw online that response.data is supposed to send back only the parsed json data but on my {{services}} I get this :
{ "status": 1, "message": "Operation success", "data": [ { "_id": "5edfdaf5586d4c75036bc853", "title": "Logo rapide", "description": "testing service desc", "createdAt": "2020-06-09T18:54:45.904Z" }, { "_id": "5edfdafd586d4c75036bc854", "title": "Logo rapide", "description": "testing service desc", "createdAt": "2020-06-09T18:54:53.054Z" }, { "_id": "5edfdc8bc07c7677915275c1", "title": "Logo rapide", "description": "testing service desc", "createdAt": "2020-06-09T19:01:31.945Z" }, { "_id": "5edfdc8cc07c7677915275c2", "title": "Logo rapide", "description": "testing service desc", "createdAt": "2020-06-09T19:01:32.621Z" } ] }
instead of the parsed data.
Thank you :)
If the response is a string then you could use:
this.services = JSON.parse(response.data).data
else if it is a JSON object already (I think it might be - but get the actual data object from your response.data):
this.services = response.data.data
Then you could use v-for and get the title with {{service.title}}
Hope it helps.
There might be an error in JSON. Axios return string when it fails to parse data into JSON.
The common error in JSON is missing quotes in param names. Compare:
JS: {x:"y"}
JSON: {"x":"y"}
This has to do with invalid JSON from the server side. You can use an online JSON validator like https://jsonlint.com/ to validate the JSON response.

React Native fetch() not outputting body in console log

I am using fetch() to get some data from an API. When testing in Postman the data is returned successfully as JSON. However, when testing from react native app on android I get a text/html response, not sure why. How can I view the body of the response from the text in console.log() to debug? When I do console.log(resp) I can not see the body.
const response = await fetch('https://web.com/api/usersignup', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
})
.then(resp => {
this.setState({spinner: false});
console.log(resp);// output in console is pasted under this code
return resp.text();
//return resp.json();
})
.then((responseJson) => {
console.log(responseJson);
})
.catch(error => {
this.setState({spinner: false});
Alert.alert('Error', error.message);
throw error;
});
Output I get in Metro Builder when using console.log(). Does not include body.
Response {
"_bodyBlob": Blob {
"_data": Object {
"blobId": "63acc7d8-bd8a-4dd7-b33b-f0e4f202f97e",
"offset": 0,
"size": 0,
},
},
"_bodyInit": Blob {
"_data": Object {
"blobId": "63acc7d8-bd8a-4dd7-b33b-f0e4f202f97e",
"offset": 0,
"size": 0,
},
},
"headers": Headers {
"map": Object {
"cache-control": "public, max-age=0",
"connection": "keep-alive",
"content-length": "0",
"content-type": "text/html; charset=UTF-8",
"date": "Sat, 09 Nov 2019 21:06:05 GMT",
"server": "Apache",
"x-ratelimit-limit": "60",
"x-ratelimit-remaining": "59",
},
},
"ok": true,
"status": 200,
"statusText": undefined,
"type": "default",
"url": "https://web.com/api/usersignup",
}
You cannot print the body until the promise of first then is finished.
I made an example with your code: https://snack.expo.io/#egizas/fetch-print-body
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
//body: JSON.stringify(formData)
})
.then(resp => {
console.log('Printing out not json');
console.log(resp);
return resp.json();
})
.then((responseJson) => {
console.log('Printing out json');
console.log(responseJson);
})
.catch(error => {
this.setState({spinner: false});
Alert.alert('Error', error.message);
throw error;
});
Just replace the endpoint and provide correct header.