FaunaDB returns empty array (FaunaDB + Netlify + VueJS) - netlify

My code is based on the repository - https://github.com/ttntm/recept0r-ts
Code from "\functions\read-all.js":
const faunadb = require('faunadb');
const fnHeaders = require('./_shared/headers.js');
exports.handler = (event, context) => {
const client = new faunadb.Client({
secret: process.env.FAUNA_SECRET,
domain: 'db.fauna.com',
scheme: 'https',
port: '443'
});
const q = faunadb.query;
const headers = { ...fnHeaders };
const origin = event.headers.Origin || event.headers.origin;
headers['Access-Control-Allow-Origin'] = origin ? origin : '*';
return client.query(q.Paginate(q.Match(q.Index('all_users'), false), { size: 500 }))
.then((response) => {
const listRefs = response.data;
const getListDataQuery = listRefs.map(ref => q.Get(ref)); // create new query out of list refs, then query the refs
return client.query(getListDataQuery).then((records) => {
return { statusCode: 200, headers: headers, body: JSON.stringify(records) }
})
})
.catch((error) => {
return { statusCode: 400, headers: headers, body: JSON.stringify(error) }
});
}
Code from "\src\store\modules\data.js":
async readAll({ commit, dispatch, rootGetters })
{
const fn = rootGetters['app/functions'];
const request = await fetch(fn.readAll, { method: 'GET' });
const response = await request.json();
if (response.length > 0) {
commit('SET_ALL_RECIPES', response);
commit('SET_LAST_UPDATED', new Date); }
else {
dispatch('app/sendToastMessage', { text: 'Error loading recipes. Please try again later.', type: 'error' }, { root: true });
return 'error';
}
}
Everything seems to be set. For example, this code works:
client.query(q.CreateCollection({ name: 'someCollection' }))
But can't read any data.
If launch application by "netlify dev" (localhost) - "read-all" returns empty array ("[]").
If launch application by "network" - "read-all" returns default "index.html".
I have no idea what's wrong. Maybe someone give advice...
I found a similar question - Local Netlify function server gives strange response instead of FaunaDB data
Some answer:
"In my experience, one of the most common reasons for this error is a routing problem, which is triggering a 404 response route serving HTML instead of your expected function handler."

This code works:
return client.query(q.Paginate(q.Documents(q.Collection('customers')), { size: 500 }))
.then((response) => {
const listRefs = response.data;
const getListDataQuery = listRefs.map(ref => q.Get(ref)); // create new query out of list refs, then query the refs
return client.query(getListDataQuery).then((records) => {
return { statusCode: 200, headers: headers, body: JSON.stringify(records) }
});
})
.catch((error) => {
return { statusCode: 400, headers: headers, body: JSON.stringify(error) }
});

Related

How to post a body correctly in Postman

I try to make a post request to an api but, api returns error. Although I thought about it for a long time, I could not find the cause of the error.
I think the error is due to not creating the body correctly because when I send empty array as items array the code works.
API DOCUMENTATION:
Here is my request:
module.exports.createOrder = (token, paymentId, items, callback) => {
const url = urlBase;
request(
{
url: url,
method: "POST",
json: true,
headers: {
"content-type": "application/json",
Authorization: `Bearer ${token}`,
},
body: {
secretKey: `${secretKey}`,
paymentId: paymentId,
items: items,
},
},
(error, response) => {
if (error) {
Sentry.captureException(error);
callback(errMessage, undefined);
} else {
const data = response.body;
callback(undefined, data);
}
}
);
};
Here is test values:
const testToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYyM2RmYjg4NDA4M2IwMDAyNDNjYzRhNyIsImlhdCI6MTY0ODIyOTI1NywiZXhwIjoxNjQ4MzE1NjU3fQ.9fgR3ei81vsHVMhSi8VwEyE2WMgFIMthm0PF9_zrqjw"
const paymentId = "pi_1Dq2f62eZvKYlo2Cy1moIb0G"
const variant = {
variations_values: {
color:'Black',
size:'42'
},
price:495,
product_id: "883360511078"
}
const productId = "82936941"
const quantity = 1
const item = {
variant:variant,
productId:productId,
quantity:quantity
}
let items = [item]
orderRequests.createOrder(testToken, paymentId, items, (err, data) => {
if(data){
console.log(data)
} else{
console.log(err)
}
})
I get internal server error as a response when I post these test values, but If I post an empty array as items, api does not return internal server error. What is the problem, any help?
Internal Server Error Response when I send an array with post body:
Expected request when I send an empty array with post body:

Return from module is undefined

Hi I made a module and when I try to return the song name it is just undefined, the console.log just before it works though so I'm a little confused. The line after console.log(`"${songName}" by ${artistsList}`) is where the issue is, I try to return "${songName}" by ${artistsList} but the return is just undefined so I am a little stuck on why
Code: (This is the spotify.js module)
I call it with const Spotify = require("./spotify.js"), everything works up until I need to just return the song name using the Spotify.request() function
const axios = require("axios");
module.exports = {
token: "",
ref: "",
refresh: function () {
axios({
method: "post", //you can set what request you want to be
url: "https://accounts.spotify.com/api/token",
data:
`grant_type=refresh_token&refresh_token=${this.ref}`,
headers: {
Authorization:
"Basic ",
"Content-Type": "application/x-www-form-urlencoded"
}
}).then(response => {
this.token = response.data.access_token
console.log(`Successfully refreshed token ${module.exports.token}`);
});
},
analyseSong: function (data) {
console.log(data)
const x = data;
//console.log(x)
if (x.is_playing) {
const songNameMatch = x.item.name.split("(");
var songName = x.item.name;
try {
const letter = songNameMatch[1].charAt(0);
letter.toLowerCase() == "f" ||
songNameMatch[1].toLowerCase().match(/^with/)
? (songName = songNameMatch[0].trim())
: false;
} catch (err) {
false;
}
var artistArray = [];
var artist;
const artists = x.item.artists;
//console.log(token)
for (artist in artists) {
artistArray.push(x.item.artists[artist].name);
}
//console.log(artistArray)
const artistsList = artistArray.join(", ");
//console.log(artistsList)
//console.log(`Currently playing: ${songName} - ${artistsList}`);
console.log(`"${songName}" by ${artistsList}`)
return `"${songName}" by ${artistsList}`;
} else {
return `Not currently listening to a song`;
}
},
request: function () {
axios
.get("https://api.spotify.com/v1/me/player/currently-playing", {
headers: { Authorization: `Bearer ${this.token}` }
})
.then(function (response) {
module.exports.analyseSong(response.data);
})
},
}
So I'm doing X=Spotify.request() trying to get the song name as X so I can output using IRC chat
There are a couple problems. .request() has no return value at all. So, it will never return anything other than undefined. You can fix that like this by adding two return statements, the first to return the promise itself and the second to make the return value from analyseSong() be the resolved value of that promise:
request: function () {
return axios
.get("https://api.spotify.com/v1/me/player/currently-playing", {
headers: { Authorization: `Bearer ${this.token}` }
})
.then(function (response) {
return module.exports.analyseSong(response.data);
})
},
Now Spotify.request() will return a promise that will resolve with the value returned from .analyseSong(response.data). You would use that promise like this:
Spotify.request().then(result => {
console.log(result);
}).catch(err => {
console.log(err);
});

Next Js build give error 500 internal server error in some routes

I'm trying to make the page in question getServerSideProps because the content is list of products through API so getStaticProps isnt going to help with this page.
but unfortunately all the pages work perfectly on localhost but when i deploy on vercel the page in question is giving me 500 internal server error.
any help?
build log:
error:
folder structure:
export async function getStaticProps(context) {
const { host } = context.params;
const headersTn = {
domain: "tn",
};
const headersDz = {
domain: "dz",
};
const headersCi = {
domain: "ci",
};
const resTn = await fetch(`${process.env.urlApi}v1/getProductsByCountry/`, {
headers: headersTn,
}).then((res) => res.json());
const resDz = await fetch(`${process.env.urlApi}v1/getProductsByCountry/`, {
headers: headersDz,
}).then((res) => res.json());
const resCi = await fetch(`${process.env.urlApi}v1/getProductsByCountry/`, {
headers: headersCi,
}).then((res) => res.json());
const langParam = await fetch(`${process.env.urlApi}v1/getLanguage/`).then(
(res) => res.json()
);
return {
props: {
host,
tn: resTn,
dz: resDz,
ci: resCi,
dataLang: langParam,
},
};
}
export async function getStaticPaths(context) {
const paths = context.locales.map((locale) => {
return { params: { host: `${process.env.staticHost}` }, locale };
});
return {
paths,
fallback: "blocking",
};
}

Using React, NodeJS, and Postgres: Having trouble being able to delete and updating todos

I am creating simple todo app with postgre and react.
The server side the delete and update are defined as below.
app.put("/todos/:id", async (req, res) => {
try {
const { id } = req.params;
const { description } = req.body;
const updateTodo = await pool.query(
"update todo set description = $1 where todo_id = $2",
[description, id]
);
res.json("todo updated !!");
} catch (error) {
console.error(error.message);
}
});
// delete todo
app.delete("/todos/:id", async (req, res) => {
try {
const { id } = req.params;
const deleteTodo = await pool.query("delete from todo where todo_id = $1", [
id,
]);
res.json("todo deleted !!");
} catch (error) {
console.error(error.message);
}
});
On the front end (React) this is how I am calling the update and delete
const updateDescription = async () => {
try {
handleClose();
const body = { description };
const response = fetch(`http://localhost:3000/${todo.todo_id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
console.log(response);
} catch (error) {
console.log(error.message);
}
};
Delete todo is in the other component.
const deleteTodo = async (id) => {
try {
const deleteTodo = await fetch(`http://localhost:3000/${id}`, {
method: "DELETE ",
});
console.log(deleteTodo);
setTodods(todos.filter((todo) => todo.todo_id !== id));
} catch (error) {
console.log(error.message);
}
};
So when I am doing delete or put request its not updating it in the DB.
On the browser console I am getting this error.
Failed to execute 'fetch' on 'Window': 'DELETE ' is not a valid HTTP method.
Edited
Response {type: "cors", url: "http://localhost:3000/3", redirected: false, status: 404, ok: false, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: false
redirected: false
status: 404
statusText: "Not Found"
type: "cors"
url: "http://localhost:3000/3"
__proto__: Response
For insert todo its working but for delete and put request its not updating in the database.
So can somebody tell me whats going wrong here ?
There is a space after DELETE, correct it should work properly. Even if its a simple todo App, its always good practice to create an enum or const when we are dealing with fixed string, i.e., we know the string would not change so that we can have consistency and skip over these kind of issues.
const METHOD = {
GET: "GET",
PUT: "PUT",
POST: "POST",
DELETE: "DELETE"
};

aws elastic search http request , error 'The bulk request must be terminated by a newline'

I have used this link to create a bulk http request using a JSON.stringified(body) like this:
const body = [ { index: { _index: 'image_2', _type: '_doc', _id: 0 } },
{ imageKey: 'test' },
{ index: { _index: 'image_2', _type: '_doc', _id: 1 } },
{ imageKey: 'test2' } ]
but I keep getting the error
{ statusCode: 400,
body: '{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"The bulk request must be terminated by a newline [\\\\n]"}],"type":"illegal_argument_exception","reason":"The bulk request must be terminated by a newline [\\\\n]"},"status":400}' }
I already tried this below and it is not working either:
const body = `${JSON.stringified(body)\n}`;
any ideas are appreciated :)
here is my aws elastic search function:
function elasticsearchFetch(elasticsearchDomain, endpointPath, options = {}, region = process.env.AWS_REGION) {
return new Promise((resolve, reject) => {
const { body, method = 'GET' } = options;
const endpoint = new AWS.Endpoint(elasticsearchDomain);
const request = new AWS.HttpRequest(endpoint, region);
request.method = method;
request.path += endpointPath;
request.headers.host = elasticsearchDomain;
if (body) {
request.body = body;
request.headers['Content-Type'] = 'application/json';
request.headers['Content-Length'] = request.body.length;
}
const credentials = new AWS.EnvironmentCredentials('AWS');
const signer = new AWS.Signers.V4(request, 'es');
signer.addAuthorization(credentials, new Date());
const client = new AWS.HttpClient();
client.handleRequest(request, null, (res) => {
res.on('data', (chunk) => {
chunks += chunk;
});
res.on('end', () => resolve({ statusCode: res.statusCode, body: chunks }));
}, error => reject(error));
});
}
and here is the code for my lambda function using the above request signer:
const elasticsearchFetch = require('rms-library/fetch');
exports.handler = async ({ imageID, bulk, products }) => {
if (!Array.isArray(products) || !imageID) {
throw new Error('error in bulk operation');
}
const bulkList = [];
products.forEach((product, i) => {
bulkList.push({ index: { _index: imageID, _type: '_doc', _id: i } });
bulkList.push(product);
});
bulkList.push('');
console.log('bulkList', bulkList);
const result = await elasticsearchFetch.elasticsearch(
process.env.ELASTIC_SEARCH_DOMAIN,
'_bulk',
{ method: 'PUT', body: JSON.stringify(bulkList) },
);
console.log(result);
};
Ok, first of all you need to use POST instead of PUT with the _bulk endpoint and the body cannot be a stringified JSON array.
Try like this instead:
const result = await elasticsearchFetch.elasticsearch(
process.env.ELASTIC_SEARCH_DOMAIN,
'_bulk',
{ method: 'POST', body: bulkList.map(json => {return JSON.stringify(json);}).join('\n') + '\n' },
);

Resources