Hi All

I upgraded my drupal 6 install services module to the latest version 6.x-2.x-dev (2009-Dec-06) but now my views.get is not outputting all the fields that it was before.

I have a simple view that lists all nodes of a certain content type. these nodes themselves are using the cck node reference to reference other nodes. I have set my view row style to node and views displays my data all ok.

If I go into services and do a views.get with my views name, all I get is an array list of just the referenced nids, before it would display the title field and all other cck fields with it.

I am connecting via flash and it no longer works.

any help would be greatly appreciated as this is a demo project Im working on for a client.

Regards
Barry

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

amitaibu’s picture

Title: views.get missing fields » views.get method changed in DEV version
Component: User interface » Code
Category: bug » support
Priority: Critical » Normal

Note that the views.get fields have changed - use the services browser, to see the new fields and their help

barrygearing’s picture

I have looked into the service browser but dont see anything different, I am still making sure I pass in the required options

The fields im talking about are the fields returned from my views request?

I have attached the results I am getting from the service browser. this list before the patch use to be filled with fields of data.

Regards
Barry

barrygearing’s picture

FileSize
26.47 KB

Image attached

amitaibu’s picture

Is your "Default" display_id returning all the fields, or is it another display_id?

barrygearing’s picture

Hi Amitaibu, Thanks for your reply, no my default view is not returning the full list of fields from the nodes that I want to display.

I have re applied the patch from this issue that I thought was going to be implemented into the new dev. http://drupal.org/node/329048 #57 and my view.get is working ok again.

will this be implemented?

with regards to the "display id" I see that you can set that in the services broswer, where do you find the display id?

Thanks again

Regards
Barry

mcfilms’s picture

I am developing a Drupal-backed Flash site right now and I'm confused. Can I expect views.get to be supported in the future? What is the current status? I can see the information I will need inside the services browser when I enter my view in the method section.

But I am having all kinds of trouble, most of which is due to my lack of knowledge. I see people online also having trouble. I just want to make sure I am heading in the right direction and not for a dead end.

I have the Flash With Drupal book. But the documentation for views.get is limited to bringing in a list of node titles. It also references 6.x-0.12 and mentions problems with the 2.0 version on the publisher's site.

I am hoping to convert an entire series of fully-populated nodes to objects in Flash. By "fully-populated" I mean Flash objects with text, images, url links and other cck text fields in them. Is there an example of this being done with the current version of views.get anywhere ob the internet?

jpwarren00’s picture

We're having the same problem with the latest version of services changing the output from "views.get". Does anyone know if this is an actual API change, or has this been determined to be a short term bug? Has anyone found an easy workaround or patch file for this?

-John W

amitaibu’s picture

This is an actual API change. Did you change your view.get query (as the fields have changed)?

barrygearing’s picture

Hi Amitaibu

If this is now an API change, how are we now suppose to use views.get?

I have reverted back to my patch as stated above just to get values from drupal to flash otherwise views.get currently servers no purpose to me.

Regards
Barry

klamoureux’s picture

Further to Barry's request, if there are changes to the view.get query...is there a documentation available as to what those changes are?

I tried a format_output of True, which does return the entire node as rquired, but in HTML format. A similar change to False, however, also returns an HTML version. Removing it all together, returns me to jsut the Node ID being returned, none of the other node array fields are passed.

Any ideas on how to get this working as it was?

barrygearing’s picture

Any updates on this or response to the documentaion on how to get it working with the new API?

klamoureux , my post above has a link to a patch I am still using just so I can keep my flash and views.get working ok. Looking through that post that patch was suppose to be placed into the new API but I dont know why it wasnt and havent had a response yet.

Regards
Barry

klamoureux’s picture

Thanks for that barry...i was able to get it working again with that patch.

mcfilms’s picture

Arrrrghhh... THIS is why my views.get broke when I updated to the 12.25.2009 version of the dev version of Services. I guess I somehow assumed that the patch from November was rolled into that version. Especially since that thread said it was... http://drupal.org/node/329048

Anyway, I will try and bring this to the maintainer od the Services module so that views.get can one day be working again.

amitaibu’s picture

Status: Active » Postponed (maintainer needs more info)

can anyone export their view, so we se what's not working. Or better debug the problem I suspect the problem is mis-use of the new function.

jpwarren00’s picture

Here is a view that our Flash guy made and some of the Actionscript he's attaching it to. If this is not the correct way to use it, please document the correct method for using the new version of views.get.

Thanks,
-John W

$view = new view;
$view->name = 'Test_view';
$view->description = '';
$view->tag = '';
$view->view_php = '';
$view->base_table = 'node';
$view->is_cacheable = FALSE;
$view->api_version = 2;
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
$handler = $view->new_display('default', 'Defaults', 'default');
$handler->override_option('fields', array(
  'title' => array(
    'label' => 'Title',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'target' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'empty' => '',
    'hide_empty' => 0,
    'empty_zero' => 0,
    'link_to_node' => 0,
    'exclude' => 0,
    'id' => 'title',
    'table' => 'node',
    'field' => 'title',
    'relationship' => 'none',
  ),
  'field_sub_title_value' => array(
    'label' => 'Sub title',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'target' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'empty' => '',
    'hide_empty' => 0,
    'empty_zero' => 0,
    'link_to_node' => 0,
    'label_type' => 'widget',
    'format' => 'default',
    'multiple' => array(
      'group' => TRUE,
      'multiple_number' => '',
      'multiple_from' => '',
      'multiple_reversed' => FALSE,
    ),
    'exclude' => 0,
    'id' => 'field_sub_title_value',
    'table' => 'node_data_field_sub_title',
    'field' => 'field_sub_title_value',
    'relationship' => 'none',
  ),
  'field_teaser_body_value' => array(
    'label' => 'Teaser Body',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'target' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'empty' => '',
    'hide_empty' => 0,
    'empty_zero' => 0,
    'link_to_node' => 0,
    'label_type' => 'widget',
    'format' => 'default',
    'multiple' => array(
      'group' => TRUE,
      'multiple_number' => '',
      'multiple_from' => '',
      'multiple_reversed' => FALSE,
    ),
    'exclude' => 0,
    'id' => 'field_teaser_body_value',
    'table' => 'node_data_field_teaser_body',
    'field' => 'field_teaser_body_value',
    'relationship' => 'none',
  ),
  'body' => array(
    'label' => 'Body',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'target' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'empty' => '',
    'hide_empty' => 0,
    'empty_zero' => 0,
    'exclude' => 0,
    'id' => 'body',
    'table' => 'node_revisions',
    'field' => 'body',
    'relationship' => 'none',
  ),
  'field_spotlight_img_fid' => array(
    'label' => 'Preview Image',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'target' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'empty' => '',
    'hide_empty' => 0,
    'empty_zero' => 0,
    'link_to_node' => 0,
    'label_type' => 'widget',
    'format' => 'url_plain',
    'multiple' => array(
      'group' => TRUE,
      'multiple_number' => '',
      'multiple_from' => '',
      'multiple_reversed' => FALSE,
    ),
    'exclude' => 0,
    'id' => 'field_spotlight_img_fid',
    'table' => 'node_data_field_spotlight_img',
    'field' => 'field_spotlight_img_fid',
    'relationship' => 'none',
  ),
  'field_full_size_img1_fid' => array(
    'label' => 'Full Size Image 1',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'target' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'empty' => '',
    'hide_empty' => 0,
    'empty_zero' => 0,
    'link_to_node' => 0,
    'label_type' => 'widget',
    'format' => 'url_plain',
    'multiple' => array(
      'group' => TRUE,
      'multiple_number' => '',
      'multiple_from' => '',
      'multiple_reversed' => FALSE,
    ),
    'exclude' => 0,
    'id' => 'field_full_size_img1_fid',
    'table' => 'node_data_field_full_size_img1',
    'field' => 'field_full_size_img1_fid',
    'relationship' => 'none',
  ),
  'field_full_size_img2_fid' => array(
    'label' => 'Full Size Image 2',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'target' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'empty' => '',
    'hide_empty' => 0,
    'empty_zero' => 0,
    'link_to_node' => 0,
    'label_type' => 'widget',
    'format' => 'url_plain',
    'multiple' => array(
      'group' => TRUE,
      'multiple_number' => '',
      'multiple_from' => '',
      'multiple_reversed' => FALSE,
    ),
    'exclude' => 0,
    'id' => 'field_full_size_img2_fid',
    'table' => 'node_data_field_full_size_img2',
    'field' => 'field_full_size_img2_fid',
    'relationship' => 'none',
  ),
  'field_inside_img1_fid' => array(
    'label' => 'Inside Thumbnail Image 1',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'target' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'empty' => '',
    'hide_empty' => 0,
    'empty_zero' => 0,
    'link_to_node' => 0,
    'label_type' => 'widget',
    'format' => 'url_plain',
    'multiple' => array(
      'group' => TRUE,
      'multiple_number' => '',
      'multiple_from' => '',
      'multiple_reversed' => FALSE,
    ),
    'exclude' => 0,
    'id' => 'field_inside_img1_fid',
    'table' => 'node_data_field_inside_img1',
    'field' => 'field_inside_img1_fid',
    'relationship' => 'none',
  ),
  'field_inside_img2_fid' => array(
    'label' => 'Inside Thumbnail Image 2',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'target' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'empty' => '',
    'hide_empty' => 0,
    'empty_zero' => 0,
    'link_to_node' => 0,
    'label_type' => 'widget',
    'format' => 'url_plain',
    'multiple' => array(
      'group' => TRUE,
      'multiple_number' => '',
      'multiple_from' => '',
      'multiple_reversed' => FALSE,
    ),
    'exclude' => 0,
    'id' => 'field_inside_img2_fid',
    'table' => 'node_data_field_inside_img2',
    'field' => 'field_inside_img2_fid',
    'relationship' => 'none',
  ),
  'field_node_queue_name_value' => array(
    'label' => 'NodeQueue Name',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'target' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'empty' => '',
    'hide_empty' => 0,
    'empty_zero' => 0,
    'link_to_node' => 0,
    'label_type' => 'widget',
    'format' => 'default',
    'multiple' => array(
      'group' => TRUE,
      'multiple_number' => '',
      'multiple_from' => '',
      'multiple_reversed' => FALSE,
    ),
    'exclude' => 0,
    'id' => 'field_node_queue_name_value',
    'table' => 'node_data_field_node_queue_name',
    'field' => 'field_node_queue_name_value',
    'relationship' => 'none',
  ),
));
$handler->override_option('filters', array(
  'type' => array(
    'operator' => 'in',
    'value' => array(
      'exhibit' => 'exhibit',
    ),
    'group' => '0',
    'exposed' => FALSE,
    'expose' => array(
      'operator' => FALSE,
      'label' => '',
    ),
    'id' => 'type',
    'table' => 'node',
    'field' => 'type',
    'relationship' => 'none',
  ),
));
$handler->override_option('access', array(
  'type' => 'none',
));
$handler->override_option('cache', array(
  'type' => 'none',
));

as3 view.get interaction using Net Connection and Responder Object. This is how i parse data objects returned from the view.get on a nodeQueue object that returns ALL the node info, most of which i do not ever use. Ideally i would like to just return an object from a custom view with only the fields i need.

		public function connectToDrupal():void {
			
			drupal= new NetConnection();
			drupal.objectEncoding = ObjectEncoding.AMF3;
			gateway = baseURL + "services/amfphp";
			drupal.connect( gateway );  // Connect to the Drupal amfphp gateway from url above
		
			trace("drupalconnectStarted : "+baseURL);
			
			var responder:Responder = new Responder( onConnect, onError);
			drupal.call("system.connect", responder);
			
			
		}
		
		public function onConnect( result:Object ):void {   // Called when Drupal returns with a successful connection.
		  	
			trace("We are connected!!!");
			
			loadView("someViewNameHere");	
		}
		
	
	
	
	private function loadView( viewName:String ):void {
		
		var nodeResponse:Responder = new Responder( onViewLoad, onError);
		drupal.call( "views.get", nodeResponse, viewName );    ////// (service method to call, responderObj, ...args)
	}

	
	override protected function onViewLoad( node:Object ):void {
		
		var tmpLength:Number = 0;
		
		for each (var item in node) { 
			tmpLength++;
			
			//trace(tmpLength + " Chapters Title : "+ item.title);
		}
		
		
		for(var i:uint = 0; i < tmpLength; i++) {
			
			var tmpT:String = node[i].title;
			var tmpText:String = node[i].body; 
			var tmpSubHead:String = node[i].field_sub_heading[0].value;
			var tmpPic:String = baseURL + node[i].field_img[0].filepath; 
			var tmpID:String = node[i].field_sku[0].value;
			
			_contentArr.push({itemID:i, title:tmpT,  subHead:tmpSubHead, bodyText:tmpText, pic:tmpPic, sku:tmpID});
			/*
			trace("view title : "+ node[i].title);
			trace("view blurb : "+ node[i].body);
			trace("view pic : " + node[i].field_img[0].filepath);
			trace("view chapter sku : "+ node[i].field_sku[0].value);
			*/
		}
		
		
		trace("Content Array Populated");
		
		dispatchEvent(new Event("DATA_LOADED"));
	}
amitaibu’s picture

@jpwarren00,

I can't use the Views - add I don't have the content types and fields. What I mean is for you to create a simple View using a story content type, that shows for example the title and the node ID. Then check the result, and if it doesn't work report what is missing.

After we find out the problem, maybe you will be able to document how to use it :)

jpwarren00’s picture

I would gladly write the documentation for anyone who drills down to the problem. Here's the associated content type:

jpwarren00’s picture

FileSize
20.98 KB

See attached

mcfilms’s picture

@ Ambitu,

Since I posted yesterday, I got some assistance on IRC from a person named voxpelli. It was suggested that regardless of what was previously posted about views.get, one should NOT use "row style:node" and must use "row style:fields". When I switched over to this, views.get works.

So I guess we can mark this issue as solved.

But Services still has some outstanding issues. I will put them down here in the spirit of constructive criticism. I recognize that a ton of work has gone into the Services module. Most of it is waaaaay above my head. I have much love for the people that are working on making Services work. The Services front page says, "please submit bug reports, patches or suggestions so that we can push it towards a release."

So here it is:

• The link to the Services Browser at services/amfphp is not valid
• The documentation is really uneven and hard to track down information. (Travis Tildwell's Flash With Drupal book was outdated before the ink dried)
• Sometimes there is conflicting information. (Case in point being the "use fields/use nodes/use fields" issue above.)
• "row style:node" Does not pass the information inside the nodes, but just a list of node numbers, which is rather useless.
• Keys and sessid are not really documented and unless you are familiar with them, you are left guessing which to choose.
• It is impossible to have services pass a link to an image without putting the image in the "Relationship" field
• Even if you do specify the image Relationship, I have found no way to point to the imagecache version of the file. It appears you can only get the file path for the original image. You must hack together your own imagecache image path.
• Taxonomy -- I was unable to get a specific Taxonomy term to return. I saw other people experienced this issue and switched to a CCK text field. (So I am not 100% sure this is an issue.)

That is my list. If it would be more helpful to post these in a different place or a different way, I'd be happy to do so.

amitaibu’s picture

@jpwarren00,

1) Please read comments #16 about the Views to create.
2) Can you confirm that mcfilms style:node >> style: fields works?

@mcfilms
1) Ambitu != Amitaibu :)
2) I'm not Services maintainer
3) You should split your ideas/ bugs into separate issues, and better - provide a patch.

mcfilms’s picture

@Amitaibu

1). I wasn't talking to you -- I was talking to that Ambitu guy -- (Okay, SORRY) :)
2). I know. HeyRocker is the Services maintainer. The second part of my post was just to open up discussion, not really directed to you (OR Ambitu).
3.) I estimate I am still a year away from learning enough to provide a patch that is useful. But I will bust these issues out into separate issues at some point or "me too" the existing ones if I have anything further to add.

I know I lost some credibility by spelling your name wrong. But for what it's worth, this is what I get when I switch back to Row style: Node from Fields:

Result

Array
(
    [0] => stdClass Object
        (
            [nid] => 6
        )

    [1] => stdClass Object
        (
            [nid] => 4
        )

    [2] => stdClass Object
        (
            [nid] => 5
        )
amitaibu’s picture

Status: Postponed (maintainer needs more info) » Active

@mcfilms,

Don't worry about it - just a little mistake ;). btw, I also started my days in Drupal as a non-developer. Best way to start is -- to start...

Regarding, your solution, I suspect this is the issue other have reported.

dstol’s picture

As has been suggested using the view field style for the image field in both the 25 Dec and 28 Jun versions of services both produce a node_data_field_img_field_img_fid, _list, and _data, which are not really useful in terms of retrieving a file path for the image itself. See jun28-services-field-style.png and dec25-services-field-style.png

Now on the other hand using the view node style for the 25 Dec and 28 Jun versions produce very different results. See jun28-services-node-style.png and dec25-services-node-style.png
It appears that the dec25 version only grabs the nids where as the 28 Jun appears to be doing a node_load or equiv and providing a whole node object to the server, which is more handy in my opinion.

I've also included my view and my story content type (has an image field)

I hope this clears things up as to what the issue with the views.get appears to be.

amitaibu’s picture

I think the best solution is to add in the views.get description a comment that one should use the fields style, otherwise Views returns only the nids, and they are later rendered using node_load().

I'd like to emphasize that Services doesn't try nor need to manipulate Views result, so the result you see with latest Dev are what you *should* get.

gdd’s picture

Amitaibu, any chance you could add some code samples to the handbook describing how a proper Views Service call should work, as well as the differences from the new version to the old one? I think it would help these support issues quite a bit.

http://drupal.org/node/113697

Thanks!

amitaibu’s picture

@heyrocker,

Porting OG7 is now eating the little spare time I have. If someone else provides a patch or docs I can review them. Whoever asked the support question and got an answer are good candidates, IMO, for this task ;)

dstol’s picture

Hmm, why not load the node? You're not doing any manipulation of the data, it just seems like you're adding another step into the process of using views.get.

  1. Load the view
  2. Loop through the return object running node.get on each nid
  3. Manipulate in js or as

Instead of

  1. Load the view object
  2. Manipulate in js or as

Correct me if I'm wrong but I feel like 99% of usage of views.get will want the whole loaded views object.

If I am wrong then using the field style on a imagefield doesn't produce all the images data, no path, just the metadata. See #23 dec25-services-field-style.png

dstol’s picture

Here's a patch to return the loaded node objects in the view.

amitaibu’s picture

@dstol,

I don't think this is the right approach. Services is using Views, and shouldn't try to manipulate by its own the output. You can already get the node itself, by using views.get and then node.load the node Id.

The patch that I expect to review is one that adds an explanation in the views.get #description about usinf style:fields instead of style:node.

dstol’s picture

Here's what you're suggesting...

App
view.get(some_view)

Server
returns array of nids

App
loop through the nids and node.get them

Server
return each node object

Here's what my patch does

App
view.get(some_view)

Server
return array of node objects

I don't see how this is an issue as the majority of the people in this thread are using services the way my patch allows them to. This isn't any manipulation of the view, no data is lost. This is the same method views uses to load it's data. The patch is just doing a node_load in the module rather then making another connection to the server with the app.

amitaibu’s picture

> Here's what you're suggesting...

Not exactly. What I suggest is using style:fields. If you need to node load, indeed you have a function for it. I don't think that node_load() multiple nodes is a better approach than loading the ones you need.

Also, your patch is node centric. Views can query also other tables (users, taxonomy, etc').

voxpelli’s picture

@Amitaibu: Generally speaking the data in $view->result doesn't necessarily map to the fields you've choosen. $view->result is the raw result of the database query made by Views and some fields contain more logic than just fetching a value from the database and showing it.

Just like the node row style only needs a nid from the database to render its content a field handler can require a nid but render something entirely different based on it.

The solution would ideally be for field handlers to expose non-rendered results in addition to rendered results. But as far as I know they currently don't and we can't really add them all ourselves.

What we can do is to re-add support for the node row style - it's a reasonable and isolated workaround for Views lack for non-rendered results I think.

amitaibu’s picture

> it's a reasonable and isolated workaround for Views lack for non-rendered results I think.

Ok guys, I see your point, but, still I think the patch should include some #description about the cost of using style:node, instead of style:fields.

mcfilms’s picture

>> The solution would ideally be for field handlers to expose non-rendered results in addition to rendered results.

YAY!!!

>> But as far as I know they currently don't and we can't really add them all ourselves.

Uhhhhhhhh.....

>> What we can do is to re-add support for the node row style - it's a reasonable and isolated workaround for Views lack for non-rendered results I think.

As a neophyte user, I'd say you are all right... Add a workable Views node solution, but document it and mention the preferred method of returning views results via services is with fields.

Much, much, more importantly, I think, is to correct the documentation pages that erroneously tell one to use nodes. I am on the hunt for these pages, and I know I didn't dream this information up, because other users were led down this same path.

dstol’s picture

Here's a slightly more compatible version of my patch in #28. It'll handle other view types. Roughly. In the event of other better methods to handle different types of vews we can always just add a new case to the switch.

voxpelli’s picture

In response to patch in #35 - why are you checking the base table? It's a special case for the node row plugin? A result can contain node fields without having a base_table as a node I believe so either the fields is never processed or always. Why should they be processed?

dstol’s picture

Well, the you check against $view->base_table because views supports node, comment, file, node revision, term and user and the $view->base_table will always be one of those. Unless I'm mistaken.

And in order to not make the patch node centric as in #31.

adub’s picture

I've been bitten by this recently. I now understand that the current behaviour is more correct but I think it's also not going to be much use to anyone. Looping through doing node_loads is bad enough but attempting that via services strikes me as a non-starter performance-wise. (You would presumably want all of those nodes since the view already filtered results.) Is there any use case for getting only nids when a view specifies node row? A big use case for using row node is when you are returning nodes of different types and don't know what fields will be in a result. The current state means that services consumers no longer have access to that strategy. I would vote for returning full node objects unless the format switch is set, in which case rendered nodes.

waldmanm’s picture

I want to second @adub's comment. For performance reasons, I want to get all the node data in one service call to the server, not loop on node.get after views.get. If one really wants only the nids, one can specify fields row and include only the nid field. In my case, I need to get much of the node data for many nodes. I also have several 'multiple value' fields such as cck taxonomy and node references and it's much harder to define the view correctly to get all the data and then parse it (Flex in my case).

I also currently have a problem where I cannot get any data when I specify the "Group multiple values" option on these fields, so my only options are to not group them and get multiple rows for each node (which requires more processing in Flex) or just get the node object, which is much easier to process. I'm still researching this and will open a separate issue - just wanted to give some more context.

@dstol - thanks for the patch. It works great. I hope it's accepted by the maintainers.

voxpelli’s picture

Status: Active » Needs work

In response to #38 and #39 regarding performance - have you looked at how the node row plugin in views does it? It's using a node_load() for every single row as well so it would be the responsibility of that plugin to come up with a faster way of performing what it's doing - not our responsibility. We should just work around not being able to receive the data from the plugin.

On a side note - Drupal 7 has if I remember correctly fixed the current performance problem of performing multiple node_load() by adding a new specific function for that. Yet another sign that the performance problem should not be fixed by us.

In response to #37 - a view can only have a single base_table - right? But tables can join with each other and eg. a comment or some data from a custom views implementation can have data from a node table joined in to it without the base_table being node. If we need to perform specific tasks on node-properties it would need another way of detecting when to run that - but I'm not sure why we would need to perform such specific tasks?

I'm moving this to needs work until we figure that part of the patch out.

Also - I marked #415314: Get filename and filepath from Services views.get as a duplicate of this issue.

voxpelli’s picture

Category: support » feature
adub’s picture

Regarding performance, looping through a node_load on the server side is not great but something we have always been stuck with < d7 and nobody proposed optimising that in views.service as far as I understood. But since this change, that option has been removed and the only one left is looping through on the client side and making a service request for each node, which is going to be much slower (even if the client makes provisions to maintain authorization between calls). It seems like we have replaced a suboptimal but standard drupal method with an unusable one. I think this has created less parity between what is going on on the server and client side even though views.service was doing additional work before and not simply wrapping the output of views_get_view(). It looks like views does the node_load as part of a template preprocess call so I'm thinking services need to handle this rather than tapping higher up in views. If we don't, the effect is that users are now left with the option of not using row node or patching views.service.

Was there anything actually broken with the previous technique or was it removed on the basis of leaky abstraction? I'd propose that this was reversed for services 2 (particularly as services 1 appears dead) and maybe looked at again for services 3 as it may indicate a more general requirement to be able to use underlying objects when transmitting data between sites.

voxpelli’s picture

I misunderstood #38 and #39 as to be critical towards server side node_loads() - sorry for that. You're of course right - client side node_loads() over the API should not be needed.

The patch in #35 with some modifications will most likely be part of Services 2 - readding the possibility of fetching complete nodes from a view.

gdd’s picture

I have not really been following this issue closely, but I would like to get some feedback from people about what should happen with the views.get method. As this issue and others have shown, several people were affected by the API change that took place a couple months ago, and I have heard from more outside the issue queue. I am pretty worried that when a stable release of Services is done, many more people will upgrade and have their code break, resulting in a huge support burden. For that reason I am thinking about reverting that change back to the original. I am interested in what people think about this.

If that happens, we could still use the new code as a secondary function (views.get2 especially, albeit named something less stupid). If anyone has other ideas I'd like to hear them.

Basically, I'd like to see some consensus appear amongst all the people here, soon, with the above concerns taken into account. I consider this the only major issue holding up the Services stable release right now.

Thanks everyone.

waldmanm’s picture

This is a critical issue for me so, at the risk of repeating myself, I would say:

1. The ideal solution here is for views.get with 'fields' row style to truly return all the fields that are defined in the view, including those that are not in $view->result (e.g., a field with multiple values that are grouped in the view). When we get this one can access any node info so the issue here becomes only one of backwards compatibility and how much support load will be generated by breaking it.

2. Until we achieve #1 above, it seems that the only efficient way to get some node fields from a view (mostly for multiple nodes) is to use 'node' row style that returns the entire node. There's some inelegance and potential waste in sending everything to the client but getting only the nids and looping in the client on node.get is far worse. So the change that was introduced a couple of months ago leaves me with no choice but to run a patched version of services. I hate doing that and really hope this will be reverted soon so I can run official code.

3. From a functionality perspective, I cannot see a need for a 'node' row style that returns only nids. If that's what you want, just define a view that returns the nids and use 'fields' row style. So I don't really see what is gained by this recent change.

4. Aside from that, there's the backwards compatibility issue you mentioned, which is especially worse here because the interface stays the same but the behavior changes. That is sure to cause major headaches for people.

Just my $0.02.

mcfilms’s picture

I agree with everything waldmanm laid out above.

I also think services should never have been changed in such a way as to break views.get. IMHO the Drupal community should make every effort to keep functions status quo once a book has been published. It's not that you owe the publisher/writer anything. It's that the book, presumably, has much more documentation and practical examples than what is available on the internet.

When the module IS released I think the revised views.get should get its own name (views.get2? sure) But the key would to be document the heck out of this difference on the Services page and in the module.

marcingy’s picture

My view is that the drop is always moving, ie apis can be changed and there is no need to preserve back comptability. However any api changes should not create a regression in terms of what the api can do, but the parameters passed in to achiveve the required response may change.

Suppose what I'm trying to say both versions old views api and new views api should be merged to create a richer set of functionality. And we should only have one interface otherwise we increase overhead in terms of maintainence and cause confusion. That said I personally think views service needs to find a new home either as part of the views module or in contrib, afterall It is an exception to the rule that 'services only supports drupal core'.

voxpelli’s picture

Here are two patches that I think restores the functionality needed.

The small one of them only restores that the full nodes are being loaded - it doesn't restore the filtering of the fields of those nodes.

The bigger one of the patches re-adds the filtering of fields for both nodes and non-nodes. Non-nodes seems like if it doesn't make sense - but since a view field can add plenty of database fields which you might not be really interested in it might be useful to filter those out just to get a cleaner result.

Noted should that I haven't tested these myself - but since I've seen no other patch since I responded last time I thought I could just as well make some to show how the problem might be solved.

amitaibu’s picture

I like the simple one better. As IMO the fields is a serivces duplication of View's fields.

 +    $row_plugin = $view->display[$view->current_display]->display_options['row_plugin'];

Not sure about the syntax, but we probably can do something like
$view->display_handler->option_get('display_option')

adub’s picture

I agree with #47 in principle and the simple patch in #48 solves my use cases. (As far as I can see, the first point in #45 is unresolved.)

voxpelli’s picture

@Amitaibu: I just copied from the old code - please feel free to reroll with any improvements :)

@adub: I think the first point in #45 is out of scope of this issue - I suggest that a solution for that are made first when the Views service has been separated from Services core.

joachim’s picture

+1 to moving the views services out to their own module.

For one thing, we may soon need two branches, to support Views 2.x and 3.x.

I volunteer for co-maintaining :)

joachim’s picture

I'm moving along quite quickly with with http://drupal.org/project/content_distribution, and it turns out I need views-related services that aren't yet there -- for instance, I need to retrieve the view as an object rather than the exported code string.

I can either define this service in Content distribution, which fractures the views services support, or this can go into views_service.
The latter seems preferable, but I need this code now, so I'm going to have to temporarily put it into Content distribution.
I'd set the ball rolling with a new views_services project, but that will clash with the module already in the Services package.

(Though -- potential bikeshed here -- should we emphasize that these are modules around Services and call it services_views?)

voxpelli’s picture

@joachim: Could you open a new issue regarding separating the views service from services core?

joachim’s picture

Sylvain Lecoy’s picture

This is a copy/paste from my http://groups.drupal.org/node/46960 comment:

I think we should implement a "Service" tab for displaying cck fields.

Let me explain.

When you go to admin/content/node-type/[TYPE]/display, you can choose to display a namespace for Default, Tokens, RSS, (and because I added the Simplenews module) Simplenews.

To respect the drupal logic and empower the Views service, a namespace display should be choosen from the brand new Service tab, this will ensure that you get the right url by configuring the display through amf or rcp.
To respect the service logic on the other hand, the tab should be named "Node" as the view service only returns id of nodes for a specific view. Then the namespace choosen in this "Node" display is returned instead of the original file.

This will avoid using a custom ImageCache module, and avoid to do 2 calls of remote function to know the exact url of the imagecache profil.

I was hard coding the base url for each namespace before, and when renamed by Drupal, ie. image2_0.jpg, flash didn't find the right file.

What do you think of this solution for improving the Views Services ?

Regards

Sylvain Lecoy
AS3 + Drupal dev

gdd’s picture

So originally I was leaning heavily towards rolling back to the original API because I was worried that we were going to be flooded with support requests when the API changed. However guess what? According to the usage stats, half the people using 2.x dev have upgraded to the beta, and the flood has not appeared. This is around 1,300 users. This is heartening to me and makes me feel a little better about leaving this as they are.

So given that, and after talking to voxpelli on IRC today, I'm now looking at the small patch from #48. Can someone here, particularly mcfilms or waldmann or anyone else with objections originally, please do some testing and see if we're addressing your issues? I'm really looking to you all to come to some concesus here, as again I am really unfamiliar with this service and its ins and outs.

@etherx, it is a little late in the dev cycle to be making a change like this, but we will soon be opening up version 3 for dev. I suggest you open a new issue and we can discuss it for that.

Also, for the record to @mcfilms, I did not know until this issue opened that there even was a Drupal/Flash book, or that it referenced Services, or anything else about it. It's not like book authors approach module developers and ask their blessing for anything they publish. While ideally, yes, such documentation would remain live for a long time, it is not my responsiblity to make sure such a thing happens, and i bristle at even the suggestion of such a thing. Any book author basing their entire premise on a module still in -dev is playing with fire.

Thanks everyone.

waldmanm’s picture

I'm using 'node' row style to get the entire node and _not_ using the 'fields' argument of the service method. So I believe the simple patch in #48 should meet my needs as it provides a way to get all node fields without resorting to looping on node.get in the client code.

I've been running with the patch in #35 till now, so I'll need to apply #48-simple to the latest beta version and test to get real-world confirmation. I'll get back with results by early next week - I hope that's good enough. But again, from looking at the code, #48 simple should be fine.

Thanks for asking.

amitaibu’s picture

I won't RTBC, as my patch changes one line of voxpelli's patch, but I think it's ready to go.

voxpelli’s picture

If Amitaibu's code works (I'm unable to test it but it looks good) - go with that patch instead :)

adub’s picture

We just applied the simple patch in #48 yesterday to beta1 and it does what we need. (I can't see the difference between that and #59.)

waldmanm’s picture

I tested beta1 with the patches in #59 and #48 (each separately ...) and both work fine.

FYI, aside from views.get, I'm also using system.connect, user.login/logout, taxonomy.getTree, node.get/save, and comment.loadNodeComments/save/load and have not seen any problems with beta1 so far. Great job!

gdd’s picture

Status: Needs review » Fixed

OK I've committed voxpelli's simple patch from above. I would really love it if someone could go to this handbook page I just made

http://drupal.org/node/720050

and update it with information about migrating from the old views.get service to the new one. That will be super helpful after we launch I think. I am planning a big handbook re-org too but this will get us started.

Thanks everyone for your help.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

newnewuser’s picture

sub