Fetch API working in options API but not in compositions API - json

I have some code that I want to convert from options API to composition API and in composition API I'm getting res.json is not a function error while the same code is working fine in options API.
Here's the code for options API
<script>
export default {
name: 'ProductComponent',
data(){
return {
productData: []
}
}
methods: {
async retrievedData(){
const res = await fetch('../productsInfo.json');
const resData = await res.json()
this.productData = resData
}
}
}
</script>
Here's the code for composition API
<script>
import { ref } from 'vue'
export default {
name: 'ProductComponent',
setup() {
const productData =ref([])
const retrievedData = async() => {
const res = await fetch('../productsInfo.json');
const resData = await res.json()
productData.value = await resData
}
}
</script>
Not using return for productData and retrievedData in setup method because this data is not being exposed.

Related

Cannot map results from API

I'm trying to dynamically generate routes in my next.js application. I have an api called getUsers that returns something like this:
{"users":[{"_id":"639a87ae8a128118cecae85b","username":"STCollier","image":"https://storage.googleapis.com/replit/images/1641322468533_db666b7453a6efdb886f0625aa9ea987.jpeg","admin":false,"likedPosts":["639e34c5991ecaea52ace9e4","639e34c7991ecaea52ace9e7","639e34c7991ecaea52ace9ea","639e39a216a642f686a28036","639e39a216a642f686a28037","639e3b3d8cdebd89d9691f97","639e3b3d8cdebd89d9691f98","639e3b3e8cdebd89d9691f9d","639e3b5a8cdebd89d9691fa0","639e3b5c8cdebd89d9691fa3","639e3b5c8cdebd89d9691fa6"],"dislikedPosts":[""]},{"_id":"639a88abc4274fba4e775cbe","username":"IcemasterEric","image":"https://storage.googleapis.com/replit/images/1646785533195_169db2a072ad275cfd18a9c2a9cd78a1.jpeg","admin":false,"likedPosts":[],"dislikedPosts":[]}
So I know the API works succesfully, but when trying to get these api results and generate a page for each username, I get an error stating:
TypeError: users.map is not a function
Here's my code for generating the routes:
//pages/user/[username].js
const Get = async (url) => {
return await fetch(url).then(r => r.json());
}
export async function getStaticPaths() {
const users = Get('/api/getUsers')
return {
paths: users.map(u => {
const username = u.users.username
return {
params: {
username
}
}
}),
fallback: false
}
}
What is wrong with my getStaticPaths() code? I know that the API is working, so why can't I map the results?
And if anyone needs the code for api/getUsers, here is that:
import clientPromise from "../../lib/mongodb";
import nc from "next-connect";
const app = nc()
app.get(async function getUsers(req, res) {
const client = await clientPromise;
const db = client.db("the-quotes-place");
let users = []
try {
const dbUsers = await db
.collection("users")
.find({})
.toArray();
users = dbUsers
return res.json({
users: JSON.parse(JSON.stringify(users)),
success: true
})
} catch(e) {
return res.json({
message: new Error(e).message,
success: false,
});
}
})
export default app
Thanks for any help!!
Modify Get method to return an async value instead of Promise.
As Get is an async method, you need the await in getStaticPaths method.
const Get = async (url) => {
let response = await fetch(url);
return await response.json();
}
export async function getStaticPaths() {
const users = await Get('/api/getUsers');
...
}

Nodejs re parse JSON

I am unsure why with mongodb and Nextjs I am having to re do JSON.parse on data that I have fetching from MongoDB.
function PodcastUpload({ data }) {
const [value, setValue] = useState('');
var eD = JSON.parse(data);
eD = eD[0]
the data is from
export async function getServerSideProps(ctx) {
const token = await getSession(ctx)
const data = await getLatestEpisodeData(token,ctx.params.podcastName)
return { props: { data } }
}
which gets the data from
export async function getLatestEpisodeData(token, showname) {
if (token) {
// Signed in
const uuid = token.uuid;
try {
const client = await clientPromise;
const db = client.db("DRN1");
const shows = await db
.collection("episode")
//.findOne({show_b: showname})
//.toArray()
.find({'show_b': showname})
.sort({_id:-1})
.limit(1)
.toArray();
return(JSON.stringify(shows));
} catch (e) {
console.error(e);
}
}
}
I have tried to remove the JSON.stringify however that brings up a SerializableError: Error serializing .datareturned fromgetServerSideProps in "/staff/podcasts/[podcastName]/upload".
Have you tried logging data in your getServerSideProps ?
I usually get this error when one of my props is undefined

API returns index.ejs HTML template instead of JSON

When trying to bring a news/posts list from a common WordPress RSS Feed (Rest API), it ends up returning my index.ejs webpack template in my app instead of the JSON response.
Using an endpoint like: example.com/wp-json/wp/v2/posts, the expected response would be a JSON "string" with a certain number of posts,
and instead it's returning a text/html response, which happens to be the html template for my app, nothing unkown.
The code in JS, React being used is:
import axios from 'axios';
const getPosts = async () => {
const postsEndpoint = '/wp-json/wp/v2/posts';
const config = {
headers: {
'accept': 'text/html, application/json',
'Content-Type': 'application/json; charset=UTF-8',
},
params: {
_limit: 5,
}
};
let response;
try {
response = await axios.get(postsEndpoint, config);
} catch (err) {
console.log(err);
} finally {
// eslint-disable-next-line no-unsafe-finally
return response.json;
}
};
export default getPosts;
And the code to show this in display:
const blogNews = () => {
const [isLoading, setIsLoading] = useState(false);
const [posts, setPosts] = useState(null);
const getPostsData = async () => {
try {
setIsLoading(true);
const data = await getPosts();
console.log(data);
if (data.status === 200) {
setPosts(data);
setIsLoading(false);
}
} catch (err) {
console.log(err);
} finally {
setIsLoading(false);
}
};
useEffect(() => {
getPostsData();
}, []);
return ...
And the nginx configuration lines looks like this:
location /wp-json/wp/v2/ {
proxy_pass http://example.com/;
}
I'm using 'text/html' in the Accept header just to see what's in the response, if I only include 'application/json' it just returns a 404 error.
The fact that I'm not including Cors nor CSP headers it's because it's because the policy criteria is being met with the nginx configuration.
Do you guys have any recommendations regarding this? Thanks in advance.

NextJS get custom JSON depending on page

I know you can do the following
export async function getStaticProps({ params }) {
console.log(params)
const res = await fetch(`https://example.com/api-access/news/2021_autumn_home_style_tips`)
const data = await res.json()
if (!data) {
return {
notFound: true,
}
}
return {
props: { data }, // will be passed to the page component as props
}
}
however what if the last part depending on the news item a user presses needs to change.
https://example.com/api-access/news/2021_autumn_home_style_tips
https://example.com/api-access/news/2020_autumn_home_style_tips
https://example.com/api-access/news/2021_car
https://example.com/api-access/news/top_songs
How can I make a [slug].js page that allows me to run that slug url for example
https://myexample.com/news/top_songs
would fetch data from https://example.com/api-access/news/top_songs
I have tried
export const getStaticPaths: GetStaticPaths<{ slug: string }> = async () => {
console.log(params)
const res = await fetch('https://example.com/api-access/news/{slug}')
const data = await res.json()
if (!data) {
return {
notFound: true,
}
}
return {
props: { data }, // will be passed to the page component as props
}
}
But get this error

Not able to download OBJ file using GetDerivativeManifest

I am trying to download an OBJ file generated from SVF file, using the Autodesk.Forge .NET API method GetDerivativeManifest (C#). The OBJ file has been created successfully. However, the method does not provide a Stream that I can use to retrieve the file and save it locally.
How can I get the OBJ file?
I don't have a C# sample ready to give you, but I hit the same issue with the Node.js SDK. I worked around by implementing the REST call myself:
download (token, urn, derivativeURN, opts = {}) {
// TODO SDK KO
//this._APIAuth.accessToken = token
//
//return this._derivativesAPI.getDerivativeManifest(
// urn,
// derivativeURN,
// opts)
return new Promise((resolve, reject) => {
const url =
`${DerivativeSvc.SERVICE_BASE_URL}/designdata/` +
`${encodeURIComponent(urn)}/manifest/` +
`${encodeURIComponent(derivativeURN)}`
request({
url: url,
method: 'GET',
headers: {
'Authorization': 'Bearer ' + token.access_token
},
encoding: null
}, function(err, response, body) {
try {
if (err) {
return reject(err)
}
if (response && [200, 201, 202].indexOf(
response.statusCode) < 0) {
return reject(response.statusMessage)
}
if (opts.base64) {
resolve(bufferToBase64(body))
} else {
resolve(body)
}
} catch(ex) {
console.log(ex)
reject(ex)
}
})
})
}
Here is how I invoke that method within my endpoint:
/////////////////////////////////////////////////////////
// GET /download
// Download derivative resource
//
/////////////////////////////////////////////////////////
router.get('/download', async (req, res) => {
try {
const filename = req.query.filename || 'download'
const derivativeUrn = req.query.derivativeUrn
// return base64 encoded for thumbnails
const base64 = req.query.base64
const urn = req.query.urn
const forgeSvc = ServiceManager.getService(
'ForgeSvc')
const token = await forgeSvc.get2LeggedToken()
const derivativesSvc = ServiceManager.getService(
'DerivativesSvc')
const response = await derivativesSvc.download(
token, urn, derivativeUrn, {
base64: base64
})
res.set('Content-Type', 'application/octet-stream')
res.set('Content-Disposition',
`attachment filename="${filename}"`)
res.end(response)
} catch (ex) {
res.status(ex.statusCode || 500)
res.json(ex)
}
})
Hope that helps