Sep 05, 2019 08:57 AM
Hi,
Here is my code using record.get([“Attachments”]); :
function showListe() {
base("Works")
.select({ view: "Grid view" })
.eachPage(function page(records) {
records.forEach(function(record) {
var li = document.createElement("li");
li.textContent = record.get(["Attachments"]);
document.getElementById("root").appendChild(li);
});
});
}
which gets me :
If i do record.get([“Attachments”][“url”);
i get nothing…
Help!
Sep 05, 2019 09:13 AM
Hi @DanielAssayag - in the API, an attachments field is an array of objects, so you need to:
['Attachments'][i]['url']
for each i
['Attachments'][0]['url']
JB
Sep 05, 2019 09:21 AM
Thanks,
I still can’t make it work but it might be my code.
What about retrieving the Attachments id, or width?
Sep 05, 2019 09:32 AM
Unfortunately, you’ve got the same issue. Even with one attachment, the API returns an array (in this case with one object):
[
{
"id": "att911J3Ml..OF2l",
"url": "https://dl.airtable.com/.attachments/117bac5e63..466918/5e2ad89d/Screenshot2019-09-05at16.23.21.png",
"filename": "Screenshot 2019-09-05 at 16.23.21.png",
"size": 32212,
"type": "image/png",
"thumbnails": {
"small": {
"url": "https://dl.airtable.com/.attachmentThumbnails/bac00690d..b31218/81919b8a",
"width": 119,
"height": 36
},
"large": {
"url": "https://dl.airtable.com/.attachmentThumbnails/6937346c0d5..37d8e5/9a38e7bb",
"width": 1094,
"height": 330
},
"full": {
"url": "https://dl.airtable.com/.attachmentThumbnails/9747be1d8c7..558f689c89/7e632201",
"width": 3000,
"height": 3000
}
}
}
]
So you’ve still got to loop through the array and use the array index to get anything
Sep 05, 2019 09:35 AM
Out of interest why are you doing record.get
there? Isn’t it something like:
record.Attachments[0].url
I’m assuming you’re in JS there and I’m only a moderately good coder, so I might be talking out of my hat!
Sep 05, 2019 11:22 AM
I dont know why, but i can get the * [object Object]
but when i use [0][“url”] it just returns nothing.
How do you retrieve the all the raw json data on the object?
Here is my current code, i’m using codesandboxio in react js to run my tests.
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
var $ = require("jquery");
var Airtable = require("airtable");
Airtable.configure({
endpointUrl: "https://api.airtable.com",
apiKey: "xx"
});
var base = Airtable.base("xx");
function App() {
return (
<div className="App">
<div id="artworks">{loadArtworks()}</div>
</div>
);
}
var loadArtworks = function() {
$("#artworks").empty();
base("Works")
.select({
sort: [
{field: 'Year', direction: 'asc'}
]
})
.eachPage(
function page(records, fetchNextPage) {
records.forEach(function(record) {
var works = $("<div>");
works.append($("<h3 class='name'>").text(record.get("Name")));
works.append($("<div class='year'>").text(record.get(["Year"])));
works.append($("<div class='typeofwork'>").text(record.get(["Type of work"])));
works.append($("<div class='dimensions'>").text(record.get(["Dimensions (cm)"])));
// nextline: this return [object Object]
works.append($("<div class='photos'>").text(record.get(["Photos"])));
// nextline: this return nothing
works.append($("<div class='photosurl'>").text(record.get(["Photos"][0]["url"])));
works.attr("id", record.getId());
$("#artworks").append(works);
});
fetchNextPage();
},
function done(error) {
console.log(error);
}
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Sep 05, 2019 02:49 PM
I was able to retrieve the json:
Here is the structure of my data :
but i don’t know how to retrieve the data inside the “Photos” field (attachment type)
Sep 05, 2019 05:45 PM
Um… assuming Photos is the name of the attachment-type field, the url of the first photo in the array should be…
Photos[0].url
You are not obligated to enumerate the collection of attachments in a field of type [attachment], but it is good practice because you really don’t know if there’s none, one, or more photos. Assuming Photos[0]. … is valid will be brittle and often may fail.
Whenever you see this, it’s an indication that each item in the array is javascript object notation (JSON) and it is addressable like any other JSON objects.
If you need to understand what’s inside that object, you can use JSON.parse() and JSON.stringify() to expose the data. But the dudes at Airtable have also provided stellar API documentation that will expose the attachment format as well.
Make sense?
Sep 06, 2019 10:55 AM
It does,
Though i still have issues retrieving attachments (sorry for that)
Here is a function i coded to retrieve data, but i can only console.log ther records and not return it in variable to parse it json. Any idea how to do it?
function loadGeneralItems(table) {
var recList = []
base(table).select().all()
.then(
function (records) {
for (let i=0; i< records.length; i++)
recList.push(records[i]._rawJson.fields)
// console.log(recList) // outputs ([Object, ...])
});
// return recList // returns nothing
}
Sep 06, 2019 01:20 PM
If you are loading all the records in a table and then enumerating them only to build yet another array representing the same records, I must ask why? Why not simply return records
? It is an array with all of the data - even the data that is in nested objects such as fields of type attachment
.
I suspect the answer is that you are groping to find a way to access the data in your attachments. That said, allow me to demonstrate how I approach this in server-side javascript (using Google Apps Script) WITHOUT using the Airtable SDK which I believe you are using.
At the outset, there’s nothing wrong with the Airtable SDK, but because it attempts to [quietly] overcome shortfalls in the API (such as true queries), I tend to develop 100% of the code required to extract Airtable data. Color me “old-school” in this example. :winking_face:
For this guide, I’ll use the Airborne Search Configuration table because it contains one record with an attachment which is a 1mb ElasticSearch index document which is a full-text index of many other bases. The field IndexRef
is a field of type attachment
and I know that extracting values from these field types if your key challenge. Here’s what the table looks like.
As a simple starting point, consider the following function - it returns only the first page of a table (just 100 records). Passing the baseKey
, tableName
, and apiKey
to this function returns the records as JSON text.
While the response is JSON, it is not parsed. More on that later.
Now, take a close look at this simple example that uses the API function call to get 100 records and enumerate them.
It will return a collection of records like this one:
What’s happening in the enumRecords function?
results
text into an array of records. Note - .records
is added outside the parsing function because we really only want the records node which is not accessible until we first parse the results
.IndexRef
is not undefined
(see line 52).url
value.And the log output looks something like this:
Final Thoughts
Note how this example doesn’t have to build a new array consisting of the data to get at the attachment data. In fact, the promise of JSON is that – aside from the parsing step – it is readily consumable as soon as your app has it.
Also note the direct access to all the fields in the attachment collection; accessing this data should be no different than accessing any other data. I suspect the SDK does this for you, but it seems that its integrated helper methods is what may be confusing you. I’m also certain that using the SDK, you can build a better version of my training code and likely with fewer lines. I don’t use the SDK so I don’t have any demo code to share with you.
Lastly, as I’m sure someone will type in the attachment URL to snoop on it, I’ll save you the trouble. It’s a Lucene-inspired full text index of the demo bases in Airtable and it is fully accessible without credentials because all Airtable attachment URLs are open and accessible to everyone. :winking_face: Ergo, be very careful when you expose attachment URLs in any context - they are public documents.