How to expand a lookupfield in a sharepoint document library using rest - javascript

I have a SharePoint(SP) library with some custom columns.
One of the columns contains a lookup field pointing to a SP list.
I need to retreive the documents in the list and all the custom fields including the fields from the lookup list (join).
There are some Q&A on stackoverflow regarding this topc, but they are about SP lists not SP document libraries.
This is what I have come up with until now (using javascript to perform a GET):
{
"url": "sites/mysite/_api/Web/GetFolderByServerRelativeUrl('/sites/mysite/myfilelibrary')
/files?$select=Name,LinkingUrl,TimeCreated,TimeLastModified,Title,ListItemAllFields
&$expand=ListItemAllFields/myListIdId"
}
This results into:
{
"value": [
{
"ListItemAllFields": {
"FileSystemObjectType": 0,
"Id": 1,
"ServerRedirectedEmbedUrl": "https://mydomain.sharepoint.com/sites/mysite/_layouts/15/WopiFrame.aspx?sourcedoc={abababab-efff-4e69-94de-128ff7c14256}&action=interactivepreview",
"ContentTypeId": "0x010100769480B9F5404447A43367BFC5B86AAB",
"Title": null,
"checkResponsible": null,
>>>>>>>>>>>>"myListIdId": 15, <<<<<<<<<<<<<<<<<<<<<
"SharedWithUsersId": null,
"SharedWithDetails": null,
"ID": 1,
"Created": "2016-07-25T06:04:56",
"AuthorId": 9,
"Modified": "2016-07-26T15:11:27",
"EditorId": 11,
"OData__CopySource": null,
"CheckoutUserId": null,
"OData__UIVersionString": "9.0",
"GUID": "898770aa-da56-40ae-9db1-430bba2da9bd"
},
"LinkingUrl": "https://mydomain.sharepoint.com/sites/mysite/myFileLibrary/Document.docx?d=w3028f42eefff4e6994de128ff7cd6e48",
"Name": "Document.docx",
"TimeCreated": "2016-07-25T13:04:56Z",
"TimeLastModified": "2016-07-26T22:11:27Z",
"Title": ""
}
]
}
The field myListIdId is returned but not expanded.
$expand=ListItemAllFields/myListIdId
should do the trick, but clearly it does not.
What am I missing?

According to this article, you specify the expanded field in the select parameter.
Revised:
"...$select=Name,LinkingUrl,TimeCreated,TimeLastModified,Title,ListItemAllFields/myListIdId
&$expand=ListItemAllFields"

Related

TypeORM Select Column from relation without using QueryBuilder

If anyway to select columns from relation without using querybuilder ???
This is my current query:
const areas = await this.areaRepository.find({
where: { ...isActive },
relations: ["division"],
});
Output :
{
"id": 1,
"version": 9,
"isActive": 1,
"createdBy": null,
"updatedBy": 1,
"createAt": "2022-04-18T15:42:12.000Z",
"updatedAt": "2022-09-23T11:04:53.000Z",
"name": "Dhaka",
"division": {
"id": 3,
"version": 1,
"isActive": 1,
"createdBy": null,
"updatedBy": null,
"createAt": "2022-04-18T15:42:00.000Z",
"updatedAt": "2022-04-18T15:42:00.000Z",
"name": "Dhaka"
}
},
But is there anything like:
const areas = await this.areaRepository.find({
select: ['id','division.id division_id']
where: { ...isActive },
relations: ["division"],
});
And the output will be:
{
"id": 1,
"division_id": 3
}
This is a duplicated question of: How to select fields from joined table using TypeORM repository?
You can check the answer here. Also this depends on which TypeOrm version you are currently using, as far as I know on version under 0.3 this doesn't work.

Assign array of JSON objects to array of interface Angular/Typescript

Currently, this works and doesn't give my error while running but my text editor is giving me an error that says property 'categories' does not exist on type 'CategoryInterface[]' (on the line where response.categories is assigned to variable) so I'm not sure if I'm doing things right.
public categories: CategoryInterface[];
.subscribe((response: CategoryInterface[]) => {
this.categories = response.categories;
console.log(this.categories);
});
My backend returns this:
{
"categories": [
{
"categoryId": 1,
"name": "Important",
"description": "This category is important.",
"order": 1,
"createdBy": null,
"createdAt": "2017-11-25 12:09:04",
"updatedBy": null,
"updatedAt": "2018-01-17 23:53:25",
"categoryBoards": [
{
"categoryBoardId": 1,
"categoryId": 1,
"name": "Announcements",
"description": null,
"order": 2,
"createdBy": null,
"createdAt": "2017-11-25 12:09:49",
"updatedBy": null,
"updatedAt": "2018-01-18 00:09:02"
},
{
"categoryBoardId": 23,
"categoryId": 1,
"name": "Rules",
"description": null,
"order": 1,
"createdBy": null,
"createdAt": "2018-01-18 00:08:57",
"updatedBy": null,
"updatedAt": "2018-01-19 00:05:51"
}
]
}
]
}
You are trying to cast your api response to an array of CategoryInterface which is not the case, you better use your subscribe method like this:
.subscribe((response: any) => {
this.categories = <CategoryInterface[]> response.categories;
console.log(this.categories);
});
It's the your api response categories which needs to be casted to CategoryInterface[]
Bonus: The angular style-guide notice that you need to declare classes instead of interfaces and you don't have to suffix the class name with Interface, so just name your CategoryInterface to Category.
You get the error because you declare response as a CategoryInterface[], but response.categories is actually the CategoryInterface[]. response is just a wrapper around the array. All the types are stripped out when the typescript is converted to javascript, which is why it works fine at runtime.

Item date sorting from API JSON in angular

I've generated some news items from a laravel API output, i display these on a angular 4 cli project. I noticed the items aren't on descending order though and I'm trying to fix this on the client side. Check it out, this is what I've got.
This is my JSON output from the api:
{
"post": [
{
"id": 17,
"creator": null,
"title": "Test artikel 4",
"content": "<p>Dit is een test artikel voor het nieuws.</p>",
"tags": null,
"photo": "website/uploads/",
"sticky": 0,
"created_at": 1506000062,
"updated_at": false,
"category": ""
},
{
"id": 20,
"creator": null,
"title": "Test artikel 3",
"content": "<p>Dit is een test. Geen sticky.</p>",
"tags": null,
"photo": "website/uploads/",
"sticky": 0,
"created_at": 1506345662,
"updated_at": false,
"category": ""
},
{
"id": 23,
"creator": null,
"title": "Hovenier 2",
"content": null,
"tags": null,
"photo": "website/uploads/1505990708_Verboon Hoveniers.jpg",
"sticky": 0,
"created_at": 1506432062,
"updated_at": false,
"category": "Test categorie 1"
}
]
}
As you can see, there is a created_at object in the array based on a unix timestamp. What I'm trying to do is sort these items based on that created_at object using angular 4 typescript.
I've tried the sort() function, but I can't seem to get it to work.
Can anyone tell what is the best way to tackle this problem? I think it must be something really simple, but I can't seem to get it.
Thanks!
edit: I have placed it in a variable, but I get this:
ERROR TypeError: Cannot read property 'sort' of undefined
also, this is the console.log from the variable.
Maybe this code can help you:
const {posts} = yourJSON;
posts.sort((a, b) => a.created_at - b.created_at);
Write the sort function like this.
var sortedPosts = data.post.sort((item1,item2) => item2.created_at - item1.created_at)
You need to do something like this.
yourObjectName.post.sort(function(a, b) {
return a.created_at - b.created_at;
});
Store your data in a variable, then sort the post property of your json object
var items = {your jsons}
items.post.sort((a,b) => a.created_at - b.created_at)

Retaining the state of an object in JavaScript & convert it into text which can be passed as parameter(as object) to another function

We have a UI where user makes selection & click on process button. On click on button, system calls a method written in JavaScript and it returns a object which looks like this.
{
"users": [{
"id": 1,
"name": "Ed",
"orders": [{
"id": 10,
"total": 10.76,
"status": "invoiced"
},{
"id": 11,
"total": 13.45,
"status": "shipped"
}]
}]
}
What I want:
I want to pass this JavaScript object to a method which should generate a text producing output like this:
{
"users": [{
"id": 1,
"name": "Ed",
"orders": [{
"id": 10,
"total": 10.76,
"status": "invoiced"
},{
"id": 11,
"total": 13.45,
"status": "shipped"
}]
}]
}
I should be able to pass a real JavaScript object to this method and by going over the object it should produce a text showcasing the structure of this object.
In .net world we can do this by using reflection and then return the string. We also have option of serializing the object into XML or JSON or any other format.
Is it possible with JavaScript.
Why I want to do this.
I have written 50 test cases which expects this object as input. I can take output of the method and pass it to any testcase.
Thank you
You should add your stringified object to some <pre> and <code> tags to get the best output.
<div><pre><code class="text"></code></pre></div>
And then use the JSON.stringify spaces parameter:
$('.text').html(JSON.stringify(obj, null, 2));
You can also use tabs if you want.
$('.text').html(JSON.stringify(obj, null, '\t'));
Fiddle
Use JSON.stringify() method. It does exactly what you need.

Handsontable Replace autocomplete values with key before posting

I am using HandsOnTable to make editing database tables more interactive on my site.
HandsOnTable fulfils nearly all my requirements except that some columns in my database actually store foreign keys rather than local string values.
In the UI I would like these columns to appear as dropdown menus where the user selects a readable value mapped to the previously mentioned foreign key (I.e. something like an HTML name/value select).
Unfortunately HandsOnTable does not have such a cell type. The closest thing to it is autocomplete. This allows me to create a dropdown, but it only contains values; no corresponding keys. Here is how it is created:
"source": ["Jebediah", "Bob", "Bill", "Buzz"]
So what I am planning is to send two Json strings from the server:
One containing the parameters needed by HandsOnTable to render the table:
{
"data": [
{ "ID": 1, "Description": "Crude", "Volume": 204, "Customer": "jebediah" },
{ "ID": 2, "Description": "Hidrogen", "Volume": 513, "Customer": "Bob" },
{ "ID": 3, "Description": "Coal", "Volume": '67', "Customer": "Bill" },
{ "ID": 4, "Description": "Wood", "Volume": '513', "Customer": "Buzz" }
],
"columns": [
{ "data": "ID", "type": "numeric" },
{ "data": "Description", "type": "text"},
{ "data: "Volume", "type": "numeric" },
{ "data": "color", "type": "autocomplete", "strict": "true",
"source": ["Jebediah", "Bob", "Bill", "Buzz"]}
]
}
The second mapping keys to values
{
"mappings": [
{"key": 0, "value": "Jebediah"},
{"key": 0, "value": "Bob"},
{"key": 0, "value": "Bill"},
{"key": 0, "value": "Buzz"}
]
}
So far so good. Now for the tricky part:
HandsOnTable has a function (getData()) that allows me to retrieve the tables data as a Json string ready to be sent back to the server:
var jdata = myHandsOnTable.getData();
Where jdata would look something like this:
"data": [
{ "ID": 1, "Description": "Crude", "Volume": 204, "Customer": "jebediah" },
{ "ID": 2, "Description": "Hidrogen", "Volume": 513, "Customer": "Bob" },
{ "ID": 3, "Description": "Coal", "Volume": '67', "Customer": "Bill" },
{ "ID": 4, "Description": "Wood", "Volume": '513', "Customer": "Buzz" }
]
Now before posting, I would like to replace that values for the Customer node with their matching pair key within the mappings json string.
How can I best achieve this in JavaScript/JQuery?
Is there a function that works something as follows?:
jdata.replaceNode('node', mappings)
Thanks
I had a similar issue and here's what I did...
For each foreign key column, I stored 2 values in handsontable; one for the id itself, which I set as a hidden column and the other is the user friendly readable text value as dropdowns.
Everytime the value of a dropdown is changed, I also change the corresponding hidden id. In my case I have a dropdown outside the handsontable as a filter which I use to map key/value pairs, but you could use Hashtables or anything else.
Now the code...
Handsontable config:
afterChange: function (changes, source) { AfterChange(changes, source); }
After change event (called everytime there is a change in the table):
function AfterChange(Changes, Source) {
if (Source === 'loadData') {
return; //don't save this change
}
var rowIndex = 0, columnID = 1, oldTextVal = 2, newTextVal = 3, ntv = '', nv = '';
$(Changes).each(function () {
if (this[columnID] === 'CategoryID') {
// Do nothing...
//To make sure nothing else happens when this column is set through below
}
else if (this[columnID] === 'CategoryName') {
ntv = this[newTextVal];
//This is where I do my mapping using a dropdown.
nv = $('#CategoriesFilterDropdown option').filter(function () { return $(this).text() === ntv; }).val();
//13 is my CategoryID column
$container.handsontable('setDataAtCell', this[rowIndex], 13, nv);
}
});
}
}
This way, you change the foreign keys as you and don't need to loop through it all before saving. It also makes it easy to send the table data as is back to server.
In summary,
The user interacts with CategoryName column (which is of type autocomplete).
The CatgoryID column is hidden to the user by setting the column width to 0 using the colWidths option of handsontable.
When the CategoryName field changes, use afterChange event to set the corresponding CategoryID column. In my case, I use a dropdown somewhere else on the page to map Name => ID, but you can use other means such as a hashtable.
I hope it makes sense...

Categories