Make JSON visible from page without using imports in vuejs - vue.js

I'm trying to make a simple webpage in Vuejs.
I have a Main.vue page, which has an import of a json file, and this json file contains certain parameters. One of them is an object array, each of its elements has a string indicating the page to be shown next in a sequence. The page also fetches data from that object.
So, the Main.vue can access to every field and object of the json file file and shows the pages (page1, page2, page3...) in a sequence, depending on the information stored at that object array.
These pages (page1, page2, page3...) need to be generic, with no reference to a specific json file, and need to show information from that specific object of the array of the json.
I know how to pass data to pages via URL (so, for example, "page1" knows which element of the array has to fetch info from because Main.vue specifies it in the URL) but I don't know how can I make MyJson accesible to "page1", "page2" without making an import sentence of MyJson in each page.
I do not have backend or something similar, just a frontend which executes entirely in the browser.
I was wondering whether there is any way of accessing MyJson from page1, page2, page3... without having a backend.
Many thanks in advance
Regards
Miguel
I have tried it by passing info via URL, but it didn't work out as expected.
PS: This is my json
MyJson.json
{
"id"="whatever"
"text"="whatever"
"myArray"=[
{
"whichPageHasToRenderMe"="page1"
"myData"= ...
...
},
{
"whichPageHasToRenderMe"="page2"
"myData"= ...
...
},
{
"whichPageHasToRenderMe"="page1"
"myData"= ...
...
},
{
"whichPageHasToRenderMe"="page1"
"myData"= ...
...
}
]
}

If you serve your json file as static file. You can use fetch api or any other fetch library to access your json file.
fetch('path/to/your.json')
.then(response => response.json())
.then(data => {
// do something
})
See more about Fetch API.
In case you want to pass some json data as url query. Don't forget to use encodeURIComponent or btoa to escape some special characters.
window.open('/some/path?data=' + encodeURIComponent(JSON.stringify(data)))

I have solved it by using Vuex and setting the JSON in the state of Vuex, so it can be accessible from other pages.

Related

Autodesk PDF Extension - Preventing page in query string override

I'm currently looking to implement pagination within the ForgeViewer PDF Extenstion, in the documentation there's a note that 'page' in the querystring will override any value passed to load model. I wondered if this was configurable or we were able to prevent this.
// URL parameter page will override value passed to loadModel
viewer.loadModel(‘path/to/file.pdf’, { page: 1 });
This is causing us a few issues as we use 'page' for other purposes and we'll have to rework quite a bit to rename our current page querystring which we're using for paginating tables.
That's correct. If you look inside the PDF extension's code (https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/extensions/PDF/PDF.js) then you'll find that this behaviour is hardcoded unfortunately 😞
I can think of two workarounds:
a) Use a URL param other than page - e.g. sheet?
b) Overwrite the current URL so that the page number will become what you need
// Original URL is: http://127.0.0.1:5500/index.html?page=2
// we change it to page=1
// This should change the URL content without a reload
history.pushState('', '', 'index.html?page=1');
viewer.loadModel("AutoCAD_Sample_Part1.pdf", {}, (model) => {
You could also achieve the same like this:
viewer.loadExtension('Autodesk.PDF').then(function(ext) {
// Original URL is: http://127.0.0.1:5500/index.html?page=2
// we change it to page=1
viewer.loadModel("AutoCAD_Sample_Part1.pdf", {}, (model) => {
ext.hyperlinkTracker.changePage(1)

Vue: Setting Data by matching route query

I'm attempting to set data fields provided by an array based on the Vue Router query. For example, when someone lands on my website using example.com/?location=texas, I want to set the location data by an array.
An example the array:
locations {
{
slug: "texas",
tagline: "Welcome to Texas",
}, {
slug: "california",
tagline: "Welcome to California",
}
}
I know this should be done using a computed property, however I am unable to get anything functioning. I've tried simple tests like if (this.slug.location === "texas"), and I cannot get the location data to populate. I would also like to provide default data in case there are no route matches.
Any help is extremely appreciated!
Edit:
I can accomplish this in a very manual way. Right now, I'm setting the query in data by the following:
slug: this.$route.query.location
I can display specific text by doing something like:
h3(v-if="slug === 'texas'") This will show for texas
h3(v-else-if="slug === 'california'") This will show for California
h3(v-else) This is default
The issue with this approach is there are various elements I need to customize depending on the slug. Is there any way I can create an array, and move whichever array matches a key in an array to the data??
You should be able to access a query param using the following (link to Vue Router documentation):
this.$route.query.location
So based on what you listed I would do something like...
export default {
computed: {
displayBasedOnLocationQueryParam() {
switch(this.$route.query.location) {
case 'texas':
return 'Welcome to Texas'
default:
return 'hello there, generic person'
}
}
}
}
Note that I'm not using your array explicitly there. The switch statement can be the sole source of that logic, if need be.

createjs loadManifest, it should be loading files in manifest, correct?

If I understand the docs correctly… 
window.queue = new createjs.LoadQueue(true, null, true);
queue.loadManifest({src: manifest, type: "manifest"}, true);
should be loading the files that are located in the json file, correct? Not seeing any requests in inspector, only getting the results array in console. Do I have to loop over results array and do the loadFile manually?
JSON is formatted correctly in a {src:"",id:"",type:"createjs.Types.IMAGE"} structure.
Any help is appreciated.
Adding more code:
function to pass in manifest url
function loadImages(manifest) {
window.queue = new createjs.LoadQueue(true, null, true);
queue.loadManifest({src: manifest, type: "manifest"}, true);
queue.on("fileload", this.handleFileLoaded);
queue.on("progress", function(event) {
console.log("progress " + event.progress);
});
queue.on("fileprogress", function(event) {
console.log("file progress " + event.progress);
});
queue.on("error", function(event) {
console.log("file error");
});
queue.on("complete", function(event) {
console.log("queue complete");
console.log(event);
});
queue.load();
return queue;
}
handleFileLoaded event is just dumping event to console at this point.
Manifest with two examples
{
"path":"https://images.unsplash.com/",
"type":"manifest",
"manifest": [
{
"src":"photo-1542838454-d4dce2a7cfde?fit=crop&w=500&q=60",
"id":"stair_boy",
"type":"createjs.Types.IMAGE"
},
{
"src":"photo-1549948558-1c6406684186?fit=crop&w=500&q=60",
"id":"night_bridge",
"type":"createjs.Types.IMAGE"
}
]}
I get access to the manifest array in the fileload event, I can manually load the images from there, but that seems counterintuitive to the whole point of using the PreloadJS. Seems like on page load, Preload should load the manifest, recognize 'type'… loop through files and in network inspector I should see the web requests for the images.
The types in your manifest are incorrect. You are passing in a string value of "createjs.Types.IMAGE". This is not equal to "image", nor is it the equivalent of the JavaScript createjs.Types.IMAGE, since it is interpretted as a string.
Instead use the string value "image"
{
"path":"https://images.unsplash.com/",
"type":"manifest",
"manifest": [
{
"src":"photo-1542838454-d4dce2a7cfde?fit=crop&w=500&q=60",
"id":"stair_boy",
"type":"image"
},
{
"src":"photo-1549948558-1c6406684186?fit=crop&w=500&q=60",
"id":"night_bridge",
"type":"image"
}
]}
Edit: The type property is only required when there is not a recognizable image extension, such as this case.
From the docs:
The loadManifest call supports four types of manifests:
A string path, which points to a manifest file, which is a JSON file that contains a "manifest" property, which defines the list of files to load, and can optionally contain a "path" property, which will be prepended to each file in the list.
An object which defines a "src", which is a JSON or JSONP file. A "callback" can be defined for JSONP file. The JSON/JSONP file should contain a "manifest" property, which defines the list of files to load, and can optionally contain a "path" property, which will be prepended to each file in the list.
An object which contains a "manifest" property, which defines the list of files to load, and can optionally contain a "path" property, which will be prepended to each file in the list.
An Array of files to load.
Your example uses the first approach. If something is not working, then feel free to post more code.
You could always throw some more events on your queue to see what is happening, such as "fileststart", "fileload", and "error". You should get at least one event when the first manifest starts loading.
Cheers.

EmberJS Route to 'single' getting JSONP

I'm having trouble with EmberJS to create a single view to posts based on the ID, but not the ID of the array, I actually have a ID that comes with the json I got from Tumblr API.
So the ID is something like '54930292'.
Next I try to use this ID to do another jsonp to get the post for this id, it works if you open the api and put the id, and actually if you open the single url with the ID on it, works too, the problem is:
When, on the front page for example, I click on a link to go to the single, it returns me nothing and raise a error.
But if you refresh the page you get the content.
Don't know how to fix and appreciate some help :(
I put online the code: http://tkrp.net/tumblr_test/
The error you were getting was because the SingleRoute was being generated as an ArrayController but the json response was not an Array.
App.SingleController = Ember.ObjectController.extend({
});
Further note that the model hook is not fired when using linkTo and other helpers. This because Ember assumes that if you linked to a model, the model is assumed to be as specified, and it directly calls setupController with that model. In your case, you need to still load the individual post. I added the setupController to the route to do this.
App.SingleRoute = Ember.Route.extend({
model: function(params) {
return App.TKRPTumblr.find(params.id);
},
setupController: function(controller, id) {
App.TKRPTumblr.find(id)
.then(function(data) {
controller.set('content', data.response);
});
}
});
I changed the single post template a bit to reflect how the json response. One final change I made was to directly return the $.ajax. Ember understands jQuery promises directly, so you don't need to do any parsing.
Here is the updated jsbin.
I modified: http://jsbin.com/okezum/6/edit
Did this to "fix" the refresh single page error:
setupController: function(controller, id) {
if(typeof id === 'object'){
controller.set('content', id.response);
}else{
App.TKRPTumblr.find(id)
.then(function(data) {
controller.set('content', data.response);
});
}
}
modified the setupController, since I was getting a object when refreshing the page and a number when clicking the linkTo
Dont know if it's the best way to do that :s

How do I get data from a background page to the content script in google chrome extensions

I've been trying to send data from my background page to a content script in my chrome extension. i can't seem to get it to work. I've read a few posts online but they're not really clear and seem quite high level. I've got managed to get the oauth working using the Oauth contacts example on the Chrome samples. The authentication works, i can get the data and display it in an html page by opening a new tab.
I want to send this data to a content script.
i'm having a lot of trouble with this and would really appreciate if someone could outline the explicit steps you need to follow to send data from a bg page to a content script or even better some code. Any takers?
the code for my background page is below (i've excluded the oauth paramaeters and other )
` function onContacts(text, xhr) {
contacts = [];
var data = JSON.parse(text);
var realdata = data.contacts;
for (var i = 0, person; person = realdata.person[i]; i++) {
var contact = {
'name' : person['name'],
'emails' : person['email']
};
contacts.push(contact); //this array "contacts" is read by the
contacts.html page when opened in a new tab
}
chrome.tabs.create({ 'url' : 'contacts.html'}); sending data to new tab
//chrome.tabs.executeScript(null,{file: "contentscript.js"});
may be this may work?
};
function getContacts() {
oauth.authorize(function() {
console.log("on authorize");
setIcon();
var url = "http://mydataurl/";
oauth.sendSignedRequest(url, onContacts);
});
};
chrome.browserAction.onClicked.addListener(getContacts);`
As i'm not quite sure how to get the data into the content script i wont bother posting the multiple versions of my failed content scripts. if I could just get a sample on how to request the "contacts" array from my content script, and how to send the data from the bg page, that would be great!
You have two options getting the data into the content script:
Using Tab API:
http://code.google.com/chrome/extensions/tabs.html#method-executeScript
Using Messaging:
http://code.google.com/chrome/extensions/messaging.html
Using Tab API
I usually use this approach when my extension will just be used once in a while, for example, setting the image as my desktop wallpaper. People don't set a wallpaper every second, or every minute. They usually do it once a week or even day. So I just inject a content script to that page. It is pretty easy to do so, you can either do it by file or code as explained in the documentation:
chrome.tabs.executeScript(tab.id, {file: 'inject_this.js'}, function() {
console.log('Successfully injected script into the page');
});
Using Messaging
If you are constantly need information from your websites, it would be better to use messaging. There are two types of messaging, Long-lived and Single-requests. Your content script (that you define in the manifest) can listen for extension requests:
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.method == 'ping')
sendResponse({ data: 'pong' });
else
sendResponse({});
});
And your background page could send a message to that content script through messaging. As shown below, it will get the currently selected tab and send a request to that page.
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendRequest(tab.id, {method: 'ping'}, function(response) {
console.log(response.data);
});
});
Depends on your extension which method to use. I have used both. For an extension that will be used like every second, every time, I use Messaging (Long-Lived). For an extension that will not be used every time, then you don't need the content script in every single page, you can just use the Tab API executeScript because it will just inject a content script whenever you need to.
Hope that helps! Do a search on Stackoverflow, there are many answers to content scripts and background pages.
To follow on Mohamed's point.
If you want to pass data from the background script to the content script at initialisation, you can generate another simple script that contains only JSON and execute it beforehand.
Is that what you are looking for?
Otherwise, you will need to use the message passing interface
In the background page:
// Subscribe to onVisited event, so that injectSite() is called once at every pageload.
chrome.history.onVisited.addListener(injectSite);
function injectSite(data) {
// get custom configuration for this URL in the background page.
var site_conf = getSiteConfiguration(data.url);
if (site_conf)
{
chrome.tabs.executeScript({ code: 'PARAMS = ' + JSON.stringify(site_conf) + ';' });
chrome.tabs.executeScript({ file: 'site_injection.js' });
}
}
In the content script page (site_injection.js)
// read config directly from background
console.log(PARAM.whatever);
I thought I'd update this answer for current and future readers.
According to the Chrome API, chrome.extension.onRequest is "[d]eprecated since Chrome 33. Please use runtime.onMessage."
See this tutorial from the Chrome API for code examples on the messaging API.
Also, there are similar (newer) SO posts, such as this one, which are more relevant for the time being.