so I'm making a discord bot as a small project and when I try to get the url from an image attachment it shows up as undefined.
here's my code:
var attachment = message.attachments
if (message.content.includes("is dropping 3 cards!")) {
let image = attachment
console.log(image.url)
}
when I use this code the image url shows up as undefined and I don't know why. I've tried using image without .url and the url seems to show up but when I use .url it doesn't seem to work.
Now now, message.attachments contains an array. The attachment can be image, video or file. There can be also multiple attachments in one message. Meaning that you need to define which one of the attachments you want to use. You should also check if there is any attachments in the message before going forward.
Below is little example for using the first file/image in the message:
if(message.attachments.size > 0) {
var attachment = message.attachments.first();
console.log(attachment.url)
}
Try console logging just attachment and seeing if that gives you any results. It should return an array of attachments which you would either need to map through or set an index value to your attachment ie. attachment[0].url. Also, there's no need for declare the image variable as its not saving you any time. attachment.url is the same thing as image.url and it just makes things more confusing than it needs to be.
Related
I'm creating a component to upload a picture and then display it after the picture is uploaded. However, I'm getting the response link of the image with a double quote and the <img> tag adds another double quotes to the image link hence the image doesn't get displayed. I've tried .slice(1,-1) but it isn't working as well. How do I correctly display the image with just a single double quotes in the <img> tag.
<template>
<img :src="srcUrl" />
</template>
<script>
uploadFile(file) {
const formData = new FormData();
formData.append("file", file);
const request = new XMLHttpRequest();
request.addEventListener("readystatechange", () => {
if (request.readyState === 4) {
const uploadedUrl = request.response;
this.srcUrl = uploadedUrl; //getting a link with double quotes here and used slice but didn't work
}
});
request.open("POST", "BaseURI");
request.send(formData);
},
</script>
Update: you're trying to get some results from an API but we learned that it was actually a graphql one, so here is how the whole process is looking.
So, this is how a graphql playground looks like. You input your params on the left (query) and you get your result on the right, in data.
Here you can see my photo query, I have another one on the other tab.
photos query below:
query {
photos {
data {
id
}
}
}
Basically, those are equivalent to REST GET. It's just a bit more complex to understand and a totally different backend organization.
I achieved to find a make you some codesandbox to illustrate how it works, here it is: https://codesandbox.io/s/somehow-working-graphql-example-3rqvj?file=/src/components/Photos.vue
The endpoint of the gql can be found in main.js aka https://graphqlzero.almansi.me/api. You can play in it without any code, it's ready to be used as is: write your query on the left and press the "play" button !
You also do have some useful docs section on the right, it may help you somehow.
The linked project do have all the gql calls in /graphql/ and the Photos.vue is an example on a possible way to make the call (there are several). The current setup only works for a single ApolloQuery so...if you want to see the result, comment one and see the other. If they are both un-commented at the same time it will not work but it comes down to configuration and it tedious and not really interesting to replicate it there...
You may also need to hard refresh it or to relaunch the sandbox because the dynamic import is messing pretty hard here... Maybe, the simplest way would be to just clone this and try it locally tbh.
So yeah, you do have it. It is how you can fetch an URL from a graphql API and display it on your page.
I can heavily recommend you taking this quick free course on Youtube to understand a bit better how this whole thing works: https://www.youtube.com/watch?v=ygUDIeiYZNA&list=PLTRTpHrUcSB--g_8qkmycKyB0WAua9sZR
Hope it somehow helped, cannot do more right now.
In my source connector, I'm using javascript for my database work due to my requirements and parameters.
The end result is storing the data.
ifxResults = ifxConn.executeCachedQuery(ifxQuery); //var is declared
I need to use these results in the destination transformer.
I have tried channelMap.put("results", ifxResults);.
I get the following error ReferenceError: "channelMap" is not defined.
I have also tried to use return ifxResults but I'm not sure how to access this in the destination transformer.
Do you want to send each row as a separate message through your channel? If so, sounds like you want to use the Database Reader in JavaScript mode. Just return that ResultSet (it's really a CachedRowSet if you use executeCachedQuery like that) and the channel will handle the rest, dispatching an XML representation of each row as discrete messages.
If you want to send all rows in the result set aggregated into a single message, that will be possible with the Database Reader very soon: MIRTH-2337
Mirth Connect 3.5 will be released next week so you can take advantage of it then. But if you can't wait or don't want to upgrade then you can still do this with a JavaScript Reader:
var processor = new org.apache.commons.dbutils.BasicRowProcessor();
var results = new com.mirth.connect.donkey.util.DonkeyElement('<results/>');
while (ifxResults.next()) {
var result = results.addChildElement('result');
for (var entries = processor.toMap(ifxResults).entrySet().iterator(); entries.hasNext();) {
var entry = entries.next();
result.addChildElement(entry.getKey(), java.lang.String.valueOf(entry.getValue()));
}
}
return results.toXml();
I know this question is kind of old, but here's an answer just for the record.
For this answer, I'm assuming that you are using a Source connector type of JavaScript Reader, and that you're trying to use channelMap in the JavaScript Reader Settings editing pane.
The problem is that the channelMap variable isn't available in this part of the channel. It's only available in filters and transformers.
It's possible that what you want can be accomplished by using the globalChannelMap variable, e.g.
globalChannelMap.put("results", ifxResults);
I usually need to do this when I'm processing one record at a time and need to pass some setting to the destination channel. If you do it like I've done in the past, then you would first create a globalChannelMap key/value in the source channel's transformer:
globalchannelMap.put("ProcID","TestValue");
Then go to the Destinations tab and select your destination channel to make sure you're sending it to the destination (I've never tried this for channels with multiple destinations, so I'm not sure if anything different needs to be done).
Destination tab of source channel
Notice that ProcID is now listed in the Destination Mappings box. Click the New button next to the Map Variable box and you'll see Variable 1 appear. Double click on that and put in your mapping key, which in this case is ProcID.
Now go to your destination channel's source transformer. There you would enter the following code:
var SentValue = sourceMap.get("ProcID");
Now SentValue in your destination transformer has whatever was in ProcID when your source channel relinquished control.
I am currently working on an Office.js add in for Word and I am trying to insert an image from a given Url. I was reviewing the Office.js documentation which is located at :
InlinePicture class (JavaScript API for Word)
I see that they may have a built in functionality of getting the base64 representation from a img url by "getBase64ImageSrc()". The documentation on the dev office website is either misleading or incorrect.
Looking to see if anyone has built a word-addin that inserts an image from a url using "getBase64ImageSrc()"? Or am I looking in the wrong direction.
Need to elaborate more on Mike's answer, to avoid confusion.
Staffer901: you are talking about 2 different subjects on this post.
Inserting Images to the document. which i think is your bottom line question: how to insert an image with an image URL. The options that Michael mentioned, which are basically to insert classic HTML for an image, will work but i would NOT recommend you to use any of them. The reason why is because really what you are doing is storing a reference to the image that has a connection to the internet dependency, which means any user consuming that document must be connected to see the image.
What i DO recommend you to do for image insertion (permanent insertion :) ) is to use the range.insertInlinePictureFromBase64 method. You need to have an additional step to encode the image in the URL to a base64 string, which is what the methods accepts as input parameter and here is a good discussion on how to achieve this.. Check out a sample below showing inserting an InlinePicture on the first paragraph of the document, assumes you have the base64. Note that you can get the current insertion point and insert the pic there if needed as well. insertInlinePictureFromBase64 is a method of any objects that inherits from range, like body, paragraph, content control etc.
here is a sample:
// Run a batch operation against the Word object model.
Word.run(function (context) {
// Create a proxy object for the paragraphs collection.
var paragraphs = context.document.body.paragraphs;
// Queue a commmand to load the style property for all of the paragraphs.
context.load(paragraphs);
// Synchronize the document state by executing the queued commands,
// and return a promise to indicate task completion.
return context.sync().then(function () {
// Queue a command to get the first paragraph.
var paragraph = paragraphs.items[0];
var b64encodedImg = "iVBORw0KGgoAAAANSUhEUgAAAB4AAAANCAIAAAAxEEnAAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACFSURBVDhPtY1BEoQwDMP6/0+XgIMTBAeYoTqso9Rkx1zG+tNj1H94jgGzeNSjteO5vtQQuG2seO0av8LzGbe3anzRoJ4ybm/VeKEerAEbAUpW4aWQCmrGFWykRzGBCnYy2ha3oAIq2MloW9yCCqhgJ6NtcQsqoIKdjLbFLaiACnYyf2fODbrjZcXfr2F4AAAAAElFTkSuQmCC";
// Queue a command to insert a base64 encoded image at the beginning of the first paragraph.
paragraph.insertInlinePictureFromBase64(b64encodedImg, Word.InsertLocation.start);
// Synchronize the document state by executing the queued commands,
// and return a promise to indicate task completion.
return context.sync().then(function () {
console.log('Added an image to the first paragraph.');
});
});
})
.catch(function (error) {
console.log('Error: ' + JSON.stringify(error));
if (error instanceof OfficeExtension.Error) {
console.log('Debug info: ' + JSON.stringify(error.debugInfo));
}
});
Finally note that the setSelectedDataAsync method that Michaels mentioned, was recently updated to support image insertion, you also need to supply the base64 of the image but the benefit is that you get backwards compatibility (it will work with 2013 clients as well) here is a code sample of this:
// assumes a valid base64 is provided as the first parameter.
Office.context.document.setSelectedDataAsync(mybase64, { coercionType: 'image' }, function (result) {
if (result.status == 'succeeded')
app.showNotification("Image inserted");
else
app.showNotification("Error:" + result.error.message + " : " + error.name)
})
Consuming images from the document. This is about getting the base64 from existing images in the document. We have a body. inlinePictures collection you can use to get all the images in the document, and you use the getBase64 method to get the base64 encoded representation of the binary. I would like to know why this is confusing in the documentation, can you please elaborate on that?
I hope this is useful.
thanks and happy coding!
-Juan.
To insert an image from URL in Word, use either the Range.insertHtml method or the Document.setSelectedDataAsync method, depending on your specific scenario and goals.
It looks like there's an error in the documentation for the other method you linked to - I'll make sure that gets corrected, but I don't believe it's the API you're looking for.
I'm building my first chrome extension and I want it to track the TV series I watch and I'm currently trying to get it to save metadata on the series that I am following.
I have a content script that returns the title, the newest episode (and the URL of this episode) as well as the URL of the cover image of the series. I am currently trying to save it with some code on my background script (I have made sure to include "storage" under the permissions section of the manifest file).
So far my script looks like this (This was developed with help from Trying to save and fetch a Javascript object using chrome.storage API?):
var bkg = chrome.extension.getBackgroundPage();
response.aID = new Series(response.aTitle,response.aNewEp,response.aNewEpURL,response.aImage);
chrome.storage.sync.set(response.aID, function(){
chrome.storage.sync.get(function(val){
bkg.console.log("The saved title is: ", val.anTitle);
bkg.console.log("The saved newEp is: ", val.anNewEp);
bkg.console.log("The saved newEpURL is: ", val.anNewEpURL);
bkg.console.log("The saved imageURL is: ", val.anImage);
});
});
Problem is, the script only seems to store one response.aID at a time, so I can never store data for more than 1 TV series. Every time I try, the script seems to overwrite my previous entry. So I would like to ask whether there's any way to store more than 1 TV series at a time?
I have looked at storing an array and then pushing each new object into that array (Store an array with chrome.storage.local), but I don't quite understand the syntax involved so I'm not sure if this would work for me.
Unfortunately you didn't include the piece of code where you save your data, but i think you dont store your data with indices for the different TV series so the stored one gets overwritten everytime you store another one.
Anyway I would prefer storing your data in a JSON element (basically every javascript element can by converted to one but continue reading) because js provides several functions for this format which make it quite easy to use.
When opening your extension, load the data and call
var data = JSON.parse (yourloadedstring);
so the string (which should look like {"TVShows": [{"title": "How i met your mother", "url": ...}, {...}]} (look here for an explenation how JSON works) gets "translated" to an element from which you can read simply by calling
data.TVShows[0].title
or
data.TVShows[1].imageURL
You can edit this data JSON element when you add a new show for example by saying
data.TVShows[2].title = "The Big Bang Theory";
data.TVShows[2].URL= ...;
data.TVShows[2].imageURL= ...;
and save this element to chromes storage by calling
var dataToSave = JSON.stringify(data);
You have a string in your storage then, containing all information you need and you can simply parse it later like explained above :)
I hope everything is clearly to understand, if not pls ask me!
Cheers
There are two conditionals involved here:
1) When the user first enters the page, an image may not already be uploaded and nothing is shown.
2) An image may already be uploaded, in which case it should show and be overridden in real time when a new image is uploaded to replace it.
The whole uploading thing and displaying it right away is taken care of, it's just updating the image in case 2 that I'm struggling with.
When I upload the image, two things happen as can be seen here:
uploadImage('myDirective', d_canvas, 'image/png', function (error, downloadUrl) {
if (! error) {
Meteor.call('updateDatabase', versionId, downloadUrl)
Session.set('imageAvailableAt', downloadUrl)
}
})
First it calls a method to update the database to add the new url. Second it sets the same url in a Session variable. Note that no matter if an image exists or not, the url will be the same and it will overridden automatically if it does.
The image review looks like this in the template:
{{#with uploadedImage}}
<div class="preview-of-uploaded-image">
<img src="{{this}}">
</div>
{{/with}}
And the helper:
var image = Session.get('imageAvailableAt')
return image
All right, this takes care of case 1, and it will display the image very neatly when it is uploaded.
But clearly nothing will show when an image is already uploaded here, and I have played with setting the same Session variable on onRendered, but then it won't update when I upload something new. I've tried different Session variables and conditionals but no luck. I've also tried Tracker.autorun but that doesn't work at all as described in the docs so I gave that up pretty quickly as well.
What should I do?
You are facing a caching issue, the image URL is being cached by the browser and it will continue showing the old version for some time although the actual resource pointed at has been updated.
What you need to do to solve your problem is append a timestamp to the URL when modifying the collection server-side.
In your Meteor method, when updating the collection, be sure to decorate the URL with the current timestamp using something like :
Meteor.methods({
updateDatabase: function(versionId, downloadUrl){
check(versionId, String);
check(downloadUrl, String);
[...]
Collection.update({
downloadUrl: downloadUrl + "?timestamp=" + Date.now()
});
}
});