I am trying to get the Global Navigation links using a REST call.

https://sitename/sites/test/_api/navigation/menustate?mapprovidername='GlobalNavigationSwitchableProvider'&$filter=IsHidden eq 'false'" 

It seems that the filter is not working correctly, since I get all the items. Also once I call it, I would like to use Handlebars to be able to style it...but my main issue is that I am unable to filter properly.

  • Have you tried 0 or losing the single quotes? I know Yes/No fields are tricky to work with in REST. It may extend to all booleans. – wjervis Sep 25 '14 at 14:55
  • Yup. I have tried 0, No, false, with and without quotes. – Diana Sep 25 '14 at 15:15
  • What about neq true/1/yes? – wjervis Sep 25 '14 at 15:22
  • Tried those as well -.- I'm wondering if it's the way the response is coming back? There are so many sub levels before you get to the actual item you want to display. msdn.microsoft.com/en-us/library/office/… – Diana Sep 25 '14 at 15:25
  • Hmm, I tried setting odata to nometadata, which strips out some of the data returned, but the filter still does not work. Are you able to manipulate the returned data after the REST call? That may be the only approach – wjervis Sep 25 '14 at 15:43

Since you are using jQuery I would suggest to utilize jQuery.grep() to easily filter elements in array.

The following example demonstrates how to request global navigation items and filter REST result:

function getJson(endpointUrl,success,failure)
      type: "GET", 
      headers: { 
            "accept": "application/json;odata=verbose",
            "content-type": "application/json;odata=verbose"
      url: endpointUrl, 
      success: success,
      failure: failure 

function getGlobalNavigation(webUrl,success,failure)
    var navEndpointUrl = webUrl + "/_api/navigation/menustate?mapprovidername='GlobalNavigationSwitchableProvider'";


function printNodes(data){
    var nodes = data.d.MenuState.Nodes.results;

    //exclude hidden nodes
    var filteredNodes = $.grep(nodes, function(node) {
       return !node.IsHidden;

    //print nodes
function logError(error){
  • It's giving only till 2 level, if there are more than 2 level then what about that? – Manveer Singh Mar 8 '18 at 7:33
  • Thanks @VadimGremyachev. My requirement was to get all menu items that User is seeing on OOB Pages i.e., exclude hidden subsite links. I was facing issue with Navigation/Menustate REST call because I was using /_api/navigation/menustate?$filter=mapprovidername eq 'GlobalNavigationSwitchableProvider' Please make sure you use /_api/navigation/menustate?**mapprovidername='GlobalNavigationSwitchableProvider'** – Dipesh May 17 '18 at 8:48

After chatting with wjervis, since the filter does not work on _api/navigation, we needed to use the javascript to pinpoint the items I wanted to extract:

function globalNav(){ 
                    contentType: "application/json;odata=verbose", 
                    headers: { "accept": "application/json;odata=verbose" }, 
                    success:function (data){ 
                        var newData = {}, 
                        d = {}, 
                        menuState = {}, 
                        nodes = {}, 
                        results = new Array(); 

                        for(var i = 0; i < data.d.MenuState.Nodes.results.length; i++) { 
                            var result = {}; 

                            if(data.d.MenuState.Nodes.results[i].IsHidden == false){ 
                                result.CustomProperties = data.d.MenuState.Nodes.results[i].CustomProperties; 
                                result.FriendlyUrlSegment = data.d.MenuState.Nodes.results[i].FriendlyUrlSegment; 
                                result.IsHidden = data.d.MenuState.Nodes.results[i].IsHidden; 
                                result.Nodes = data.d.MenuState.Nodes.results[i].Nodes; 
                                result.NodeType = data.d.MenuState.Nodes.results[i].NodeType; 
                                result.SimpleUrl = data.d.MenuState.Nodes.results[i].SimpleUrl; 
                                result.Title = data.d.MenuState.Nodes.results[i].Title; 


                        nodes["__metadata"] = data.d.MenuState.Nodes["__metadata"]; 
                        nodes.Results = results; 

                        menuState["__metadata"] = data.d.MenuState["__metadata"]; 
                        menuState.FriendlyUrlPrefix = data.d.MenuState.FriendlyUrlPrefix; 
                        menuState.Nodes = nodes; 
                        menuState.SimpleUrl = data.d.MenuState.SimpleUrl; 
                        menuState.SPSitePrefix = data.d.MenuState.SPSitePrefix; 
                        menuState.SPWebPrefix = data.d.MenuState.SPWebPrefix; 
                        menuState.StartingNodeKey = data.d.MenuState.StartingNodeKey; 
                        menuState.StartingNodeTitle = data.d.MenuState.StartingNodeTitle; 
                        menuState.Version = data.d.MenuState.Version; 

                        d.MenuState = menuState; 

                        newData.d = d; 

                        var source1 = $("#globalNavTemplate").html(); 
                        var template1 = Handlebars.compile(source1); 

  • 1
    A lot can be cut out if you want. I wasn't sure which bit you needed, so copied all the the metadata. I put it in the discussion if you're interested. – wjervis Sep 25 '14 at 18:22
  • I used this solution as well but it does not return the custom properties which I defined on term set node. What needs to be done to get the custom properties as well? – Tolga Dec 10 '15 at 15:56
  • I am also not able to get Custom Properties in the Rest Result. is there way to get it – vinit kumar Oct 16 '17 at 11:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.