Revert or remove file with FilePond on REST API with dynamic url for uploaded image - vuejs2

This is regarding Filepond & Vue-adapter.
I have a struggle with revert / remove file after it has been uploaded. I run a PHP backend with OpenAPI 3 REST API standard and I need/want to use a dynamic url when revert/delete. I use Vue-adapter.
I use this method to return the uuid after file has been uploade to my example.com/media
process: {
onload: response => {
return JSON.parse(response)['#id']
},
If i use the revert: '/' way to remove, it will send the id as body to /media/, but I need to send it do DELETE /media/uniqueFileId route. I tried some ways with revert and remove but didnt manage to get it to be dynamic. If i use revert as a function, am i supposed to use axios or fetch to make a custom request to my endpoint or is there some other way im missing?
revert: (uniqueFileId, load, error) => {
console.log(uniqueFileId)
error('problems')
load()
}

Related

Inertia Plain Axios Request

Its a very normally requirement that a web page may have multiple API requests.
I have been Inertia.js and this works very good but it lacks a very important feature to make plain XHR requests.
However Inertia.js provides Inertia.reload() but it some cases it's not very useful.
I am looking for something like Inertia::xhr() keeping in mind that I can still use Inertia.js interceptors like onStart, onFinish etc.
Anyone can help to achieve this?
You can do plain XHR requests with Axios (which is already a dependency anyway), or alternatively use the native Fetch api.
From the docs:
Using Inertia to submit forms works great for the vast majority of situations. However, in the event that you need more fine-grain control over the form submission, there's nothing stopping you from making plain xhr or fetch requests instead. Using both approaches in the same application is totally fine!
See also here
If you do a Interia::visists it will cause a full page reload.
If you want to prevent that making a call with axios/fetch makes sense. For example, if you just want to add a comment functionality, you may not want to reload the entire page. If the page is slow, the user will feel the delay when adding the comment.
Only thing you have to take care is CSRF token. If you used axios, it should read the XSRF-TOKEN from cookie automatically.
If you use the fetch api, you would need to manually provide the CRSF token.
Meaning you have to either read it from shared data or from the cookie.
If you add it to shared data, it would look like this:
public function share(Request $request): array
{
$isAdmin = Auth::user() instanceof Admin;
return array_merge(parent::share($request), [
'csrf' => csrf_token(),
'session' => [
'notification' => session('notification'),
],
'auth' => self::share_auth(Auth::user()),
]);
}
and your fetch request would look like this:
fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': usePage().props.value.csrf
// 'Content-Type': 'application/x-www-form-urlencoded',
},
body: JSON.stringify({ name: name}) // body data type must match "Content-Type" header
});
Intertia doesn't support plain XHR request.
But we have written a package that provides very similar APIs as Inertia.
https://github.com/JoBinsJP/formjs

Vue PWA caching routes in advance

I'm hoping someone can tell me if I'm barking up the wrong tree. I have built a basic web app using Vue CLI and included the PWA support. Everything seems to work fine, I get the install prompt etc.
What I want to do, is cache various pages (routes) that user hasn't visited before, but so that they can when offline.
The reason here is that I'm planning to build an app for an airline and part of that app will act as an in flight magazine, allowing users to read various articles, however the aircrafts do not have wifi so the users need to download the app in the boarding area and my goal is to then pre cache say the top 10 articles so they can read them during the flight.
Is this possible? and is PWA caching the right way to go about it? Has anyone does this sort of thing before?
Thanks in advance
To "convert" your website to an PWA, you just need few steps.
You need to know that the service worker is not running on the main thread and you cant access for example the DOM inside him.
First create an serviceworker.
For example, go to your root directory of your project and add a javascript file called serviceworker.js this will be your service worker.
Register the service worker.
To register the service worker, you will need to check if its even possible in this browser, and then register him:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/serviceworker.js').then(function(registration) {
// Registration was successful
console.log('ServiceWorker registration successful with scope');
}, function(err) {
// registration failed :(
console.log('ServiceWorker registration failed: ', err);
});
});
}
In vue.js you can put this inside mounted() or created() hook.
If you would run this code it will say that the service worker is successfully registered even if we havent wrote any code inside serviceworker.js
The fetch handler
Inside of serviceworker.js its good to create a variable for example CACHE_NAME. This will be the name of your cache where the cached content will be saved at.
var CACHE_NAME = "mycache_v1";
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.open(CACHE_NAME).then(function(cache) {
return cache.match(event.request).then(function (response) {
return response || fetch(event.request).then(function(response) {
cache.put(event.request, response.clone());
return response;
});
});
})
);
});
Everytime you make a network request your request runs through the service worker fetch handler here first. You need to response with event.respondWith()
Next step is you first open your cache called mycache_v1 and take a look inside if there is a match with your request.
Remember: cache.match() wont get rejected if there is no match, it just returns undefined because of that there is a || operator at the return statement.
If there is a match available return the match out of the cache, if not then fetch() the event request.
In the fetch() you save the response inside the cache AND return the response to the user.
This is called cache-first approach because you first take a look inside the cache and in case there is no match you make a fallback to the network.
Actually you could go a step further by adding a catch() at your fetch like this:
return response || fetch(event.request).then(function(response) {
cache.put(event.request, response.clone());
return response;
})
.catch(err => {
return fetch("/offline.html")
});
In case there is nothing inside the cache AND you also have no network error you could response with a offline page.
You ask yourself maybe: "Ok, no cache available and no internet, how is the user supposed to see the offline page, it requires internet connection too to see it right?"
In case of that you can pre-cache some pages.
First you create a array with routes that you want to cache:
var PRE_CACHE = ["/offline.html"];
In our case its just the offline.html page. You are able to add css and js files aswell.
Now you need the install handler:
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
return cache.addAll(PRE_CACHE);
})
);
});
The install is just called 1x whenever a service worker gets registered.
This just means: Open your cache, add the routes inside the cache. Now if you register you SW your offline.html is pre-cached.
I suggest to read the "Web fundamentals" from the google guys: https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook
There are other strategies like: network-first
To be honest i dont know exactly how the routing works with SPAs because SPA is just 1 index.html file that is shipped to the client and the routing is handled by javascript you will need to check it out witch is the best strategie for your app.

Upload File to S3 bucket - vue-upload-component

I am trying to upload file to AWS S3 bucket using the vue-upload-component. I have a web api set up which returns a pre-signed url with the relevant details. I am having a hard time getting this set up to work. The documentation says that the url should be supplied as a props to the file upload component like so -
:put-action="signedUrl" //local variable which is set to the url returned from the url
I am firing the web api call once the file passes the inputFilter filter criteria which in my case just checks for a text file extention. I am able to get the correct signed url which even works when I put the url as the value for the put-action props like so -
put-action="https://s3.amazonaws.com/...."
However, when trying to set it dynamically, the start upload status says - No action configured which is odd as I am sure the variable is being set after the promise is returned from the API.
So, it seems that the component is not accepting the new value.
I have tried to set the props after the promise is returned as suggested here and even tried to re render the upload component after promise is returned as suggested here but still I am getting the same message.
What might be wrong with my approach.
Managed to get this working by setting the file level property putAction
like below -
methods: {
inputFilter(newFile, oldFile, prevent) {
if (newFile && !oldFile) {
if (doesNotPassTheFilter) {
return prevent();
}
else {
return this.$store.dispatch('getSignedUrl').then((url) => {
newFile.putAction = url;
});
}
}
}

Nuxt.js: Managing CMS collections for a statically generated website

On nuxt generate, we need to fetch all collections from the CMS. Since our website is completely static, it should be sufficient to fetch every collection only 1 time, and then make them available to all routes.
We run into issues making this happen, without exposing all our websites content to every single route.
We could use vuex to store all the content. However, we don't want a giant store object with all our websites content to be available to the client. Only during the build process, the server should have access to it and pass the content needed to every single route, eg. via asyncData()
(remember, we have a statically generated website, therefore asyncData() is never called from the client).
Example: We need the blog collection on /blog, but also on /blog/:slug, and on /press. Currently we fetch them individually:
// /pages/blog/index.vue
export default {
asyncData() {
return fetchArticles();
}
}
// /pages/blog/_slug.vue
export default {
asyncData(context) {
// made available in nuxt.config.js
return context.payload;
}
}
// nuxt.config.js
export default {
generate: {
// generate dynamic routes
routes: async function() {
const collection = await fetchArticles();
const result = collection.map(item => {
return {
route: `/blog/${item.slug}`,
// save in payload, to make available in context
payload: item
};
});
return result;
}
}
}
Problem: We are fetching the same collection twice. We want to fetch it once, and then make it available to all routes.
Expected result: Being able to
fetch every collection only 1 time
storing all the collections on the server side only, passing needed content to routes via asyncData()
on client side, not being able to access that "server-side-store"
Actual result:
having to refetch the same collection for several routes
Just fill your /blog/index.vue the same way as your single blog post, with payload.
You only need to make sure to exclude /blog path from list of static routes. You can try this https://github.com/nuxt/nuxt.js/issues/2719#issuecomment-508583281. Or make nuxt build && nuxt generate --no-build command (this way all static routes will be excluded, you'll need to specify them manually).
PS:
because context.payload is only available to the dynamic routes
I have just tried the method above and it worked.

How can we query Kibana?

How can we request Kibana with REST API to get the visualization request
and response?
Like this:
I want to do that using NodeJS to manipulate this results of Kibana.
The purpose is that I want to directly query Kibana programmatically (via REST API) to get the ES request body.
You can directly request the ES. The documentation is here
You can go to kibana\kibana-4.5.1-windows\optimize\bundles\kibana.bundle.js file,
search the function "Transport.prototype.request = function (params, cb)",
and add in the first line parent.postMessage(params.body, "*");
Now go to the controller or script that manage the iframe(iframe parent)
and add
$window.addEventListener("message", function (event) {
var data=event.data;
});
for example:
<iframe id="ifr" src="http://localhost:5601/goto/6ba8a6b8ceef3tyt454789e4fe5cf5"></iframe>
<script>
$window.addEventListener("message", function (event) {
var data=event.data;
});
</script
Now you will get the request query