I have just started learning to code in ReactJS and have come to the part where I need to hit an API to get back JSON data.
I am running this on a node server on my local which tries to build it each time I make a change - this helps because it shows me where my errors are. Unfortunately it doesn't mean I know why I am getting an error.
This is my code so far:
import React from 'react';
import './App.css';
var GetUnassignedClients = React.createClass({
unassignedClients: function () {
return $.getJSON('http://localhost/backoffice/?action=unassignedClients.getUnassingedClients')
.then((data) => {
this.setState({resultMe: data.results});
});
},
render: function() {
return (
<div>this.state.resultMe</div>
);
}
});
module.exports = GetUnassignedClients;
I will re-paste the bit that seems to be throwing the error:
return $.getJSON('http://localhost/backoffice/?action=unassignedClients.getUnassingedClients')
.then((data) => {
this.setState({resultMe: data.results});
});
The error seems to be pointing at the $ - when I wrap this all in {} then it points to the full stop (.).
Not sure if I am doing something wrong or missing something.
The $in the $.getJSON is referring to jQuery. Do you have it included in your page? Javascript is trying to parse the dollar sign and can't find it. Other possible solution is to use a separate http library (if you don't need jQuery), such as axiois or fetch for example.
Im not sure, but I thought you would hit in this way
fetch(`http://localhost:8088/api/this/is/an/api/call`)
.then(result=> {
this.setState({items:result.json()});
});
Okay turns out I was trying to use $.getJSON which is JQuery - due to building this on my local using a node server JQuery wasn't included on my local development before the production code was built.
So instead I looked into using fetch that seems to be the go to when coding in react.
I also moved this section into a componentDidMount function so the app would be loaded and then the API call would be made - not that I have a lot of data to load but it's good practice for when you do.
My working code for this section:
componentDidMount () {
fetch("http://localhost/dashboard/?action=unassignedUsers.getUnassingedUsers", {
credentials: 'same-origin'
})
.then(response => response.json())
.then(json => this.setState({data: json}));
}
I also came across a couple issues using fetch - if you need a session available to access said data then you need to specifically pass through the credentials or the API call will re-direct to the login page. At first I saw a status 200 but no data - as it successfully re-directed to the login page, but obviously there was no JSON to access here.
Related
From reading up on the management API, I think I should be able to fetch data from storyblok from inside my js. The first thing I'm trying is to export my entire space so that I can have an external backup. From reading the documentation, I think the following should work, but it gives me a 401. What is the correct syntax for this?
// spaceId is discovered in Settings / Space
fetch(
`https://mapi.storyblok.com/v2/spaces/${spaceId}/export.json`,
{
headers: {
Authorization: managementToken, // this was created in My Account / Account Settings / Personal access Token
},
}
)
.then(async (res) => {
const json = await res.json()
console.log(json)
})
.catch((err) => console.log(err));
I was also looking to export a single story, which I think the correct URL should be:
`https://mapi.storyblok.com/v2/spaces/${spaceId}/stories/${storyId}/export.json`
I can't figure out how to determine the storyId, though. I tried the UID but that didn't work and the example showed an 8 digit number. Where do I find this number?
Note: I'm in the US, and for the regular fetches I had to use the domain https://api-us.storyblok.com so I tried adding -us and that didn't work.
Note: I will eventually be trying to add and modify stories in this same js file. Also, be able to "restore" the entire space if necessary. I hope the solution to the above will be applicable to all the rest of the calls I'll be attempting.
Note: The app is written in Nuxt 3 and I'm using useStoryblok() successfully to retrieve data. I could fulfill the above requirement to back up the entire space by iterating through everything there, but that seems like more work than is necessary, and it doesn't solve my problem with the other calls I need to make.
The management API is still on v1, it's only the content API that's v2:
https://www.storyblok.com/docs/api
That probably should help with your 401. I actually also assumed I had to use v2 :)
As how to get the story ID: yes, it's the simple ID, not the UUID.
You get it by listing some stories .../v2/spaces/SPACEID/stories?with_slug=abc.
Or look at the draft/published JSON in the Storyblok UI.
Firstly, sorry if my english is bad, i'm not native.
My problem is simple : i already succeded at post some form data from VueJS to ExpressJS API using axios just like that:
axios.post('urlOfMyAPI', this.body).then(response => this.rep = response.data);
The "this.body" thing is an object called body and inside this object, i map all my inputs, like that by example:
<v-textarea v-model='body.text'></v-textarea>
It work well, expressJS can take the data and do the job but when i try to do it with a "v-file-input", all the data inputs go to the API correctly, except the file. When i'm trying to console.log in my API (see the screen under) a random data from input in my API, the data is rendered in my console but the data file is rendered as "undefined".
Have to say one last thing : When i do "console.log(this.body)" in vueJS before the axios post, my file is in the body like expected, so the problem is with axios. I tried to find something on internet but just got some things with a "FormData" object i don't understand and tried to use without success.
My API Code btw, just for example :
exports.Create = (req,res) => {
console.log(req.body.text);
console.log(req.body.file.name);
}
Thanks you if you help me
You have to use formData when submitting files to axios, otherwise, your files won't be available on server-side.
This is a simple method that performs an upload of a file. Please note: if you want to send additional data within your request, you have to add as many formData.append() as you have properties.
uploadAvatar () {
const formData = new FormData()
formData.append('avatar', this.file)
formData.append('other_field', this.otherField)
axios.post('/avatars/upload', formData)
.then((response) => {
console.log(response.data)
})
.catch((e) => {
console.log(e)
})
}
From my experience, if you have a huge form and you want to avoid many formData.append(), the best option is to handle your uploads separately.
Im using vue.js with nuxt.js, I'm just still confused as when to use Data VS Async Data. Why would I need to use Async data when I just have data that just displays on the page?
I have a data object of FAQ's and just want to display the data without doing anything with it. What are the benefits of using the asyncData? Or what are the cases or best use of them?
Should I display list data such as this as async by default if using data such as this inside of my component?
Data
data:() => ({
faqs:[
{"title":"faq1"},
{"title":"faq2"},
{"title":"faq3"},
]
}),
asyncData
asyncData(context) {
return new Promise((resolve, reject) => {
resolve({
colocationFaqs:[
{"title":"faq1"},
{"title":"faq2"},
{"title":"faq3"},
]
});
})
.then(data => {
return data
})
.catch(e => {
context.error(e);
});
},
asyncData happes on the serer-side. You cant access browser things like localStorage or fetch() for example but on the ther hand you can access server-side things.
So why should you use asyncData instead of vue cycles like created?
The benefit to use asyncData is SEO and speed. There is this special context argument. It contains things like your store with context.store. Its special because asyncData happens on server-side but the store is on the client side usually. That means you can get some data and then populate your store with it and somewhere else you display it. The benefit of this is that its all server-side and that increase your SEO so for example the google crawler doesnt see a blank page
why would I need to pre render it when it is going to be displayed
anyway
Yes for us it doesnt matter if i send 1 File to the client and it renders all data like in SPA's or if its pre-rendered. But it doesnt matter for the google crawler. If you use SPA mode the crawler just sees a blank page. You can discoverd it too. Go to any SPA website and click right-click and inspect you will see thats there only 1 Div tag and few <script> tags. (Dont press F12 and inspect like this thats not what i mean).
On the front page of a website served with a Gatsby React setup I have a NavbarExtra component that shows some data via an api. The data coming from that endpoint changes several times a day.
The idea now is now to optimize the fetch so the fetch is made as seldom as possible so the api is used as rearly as possible, it has a limit to it(different paid plans).
The scenario should be that as long as the user has entered the site the fetch will only happen at once. Then the user can go around the site maybe close even the component with the fetch and again go back to the front-page where the fetch is made.
Now the component is called in the navmenu if the user is only on the front page:
{isLandingPage && <NavBarData/>} and in that component there is this fetch:
useEffect(() => {
fetch(
'https://endpoint',
{
method: 'GET',
headers: {
},
}
)
.then(response => {
if (response.status >= 200 && response.status <= 299) {
return response.json();
}
throw Error(response.statusText);
})
.then(data => {
const { result } = data.quoteResponse;
setNumbers(result));
})
.catch(error => {
console.log(error);
});
}, 0);
Firstly I would like to ask for how should this fetch be done so the api is used as rearly as possible, so the user gets the recent data and only gets it again when for example reloading the page?
Secondly I understand some concepts about single page apps and static site generators as here the used Gatsby, and probably have understood it right that if I would like to use the fetched data on different pages(even other pages than the isLandingPage) of the website I could just use it in one component that is served on different pages and it would not refetch on each page enter?
You could create a Parent component that fetches the data and can retrieve the data to the childrens, so you only control the fetch in one component only one time on each session, or wherever you need it. In this case depending on you architechture you could use simple stateor the context API to reuse this data on several and nested components.
Other solution could involve using the localStorage, so you could store the data fetched on the localStorage and reuse this data on any component, you just will have to update the data when you need it.
I'm trying to export a certain page from my Angular/nodeJs application using "pdfmake" and have it show up as a download option on the same page after having heard that the best way to export pdf's is through the back-end. After reading the guide and following a tutorial, however, the code writes data to my header but doesn't appear to do anything else.
In the past I've tried following the tutorial below and have read through the method documentation of pdfmake.
https://www.youtube.com/watch?v=0910p09D0Sg
https://pdfmake.github.io/docs/getting-started/client-side/methods/
I'm uncertain whether pdfmake is only supposed to be used by 'headless chrome' (of which I don't possess much knowledge) and wonder if my method can work.
I've also tried using the .download() and .open() functions with pdfMake.createPdf() which resulted in errors.
NodeJs code
router.post('/pdf', (req, res, next) => {
var documentDefinition = {
content: [
'First paragraph',
'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines'
]
}
const pdfDoc = pdfMake.createPdf(documentDefinition)
pdfDoc.getBase64((data) => {
res.writeHead(200, {
'Content-Type': 'application/pdf',
'Content-Disposition': 'attachment;filename="filename.pdf"'
});
const download = Buffer.from(data.toString('utf-8'), 'base64');
res.end(download);
})
})
Angular code
savePDF() {
this.api.post('/bookings/pdf')
.then(res => {
console.log(res);
});
}
In this case the savePDF() function is called when the user clicks on a button on the web page.
Because nothing was happening upon clicking the button I decided to console.log the result which showed up as a very long string of data.
The pdf document data only contains testdata for now as I was trying to get a download link to work before trying to download the webpage itself.
I can also assure you that there is nothing wrong with the routing and the functions are called properly.
I expected the savePDF() function to start a download of a pdf containing the test data shown in the NodeJs "documentDefinition" content, but the actual result did seemingly nothing.