Grocery crud : How to get the current id that had been used when editing and viewing a record? - grocery-crud

How to get the current id that had been used when editing and viewing a record?
I am currently following the instruction by Alfonso Secas that he posted in this topic..
http://www.grocerycrud.com/forums/topic/1326-how-to-use-grocery-crud-and-image-crud-together/page-2
And now on the part where he said "When editing a record, get the current ID from $this->getStateInfo(); to compose the iframe's source url."
It seems like getStateInfo doesn't exist yet so it shows an error "Fatal error: Call to undefined method Examples::getStateInfo() "

http://www.grocerycrud.com/documentation/options_functions/getState
this will do what u want . give it a try
u need to use the CRUD object to call this function instead of $this ..

You have some options:
Primary key
getStateInfo()->get_primary_key
Last uri segment
end($this->uri->segments)
Does not work in list action.

As a workaround you can use one of CodeIgniter's methods to get id from page url
https://www.codeigniter.com/userguide3/libraries/uri.html
You need to take last segment from URI
$segmentsCount = $this->uri->total_segments();
$itemID = intval($this->uri->segment($segmentsCount));
p.s. it is not best solution but it can do the trick

Related

Netsuite Invalid API usage. You must use getValue to return the value set with setValue

So I have an odd issue, When I create a new transaction and save, this error in the title gets thrown. But when I edit this transaction after it was created, the getText does not throw this error. Is there something I'm doing wrong or something special needed to getText on a create new record? Here is my code. This is for the afterSubmit method on my User Event Script for Vendor Bill screen. I just noticed getValue does work on create, does not produce this error, just don't understand why? Is this the correct way to get the value on create? To use getValue and getText cannot be used on create? Only for edit?
if (scriptContext.type == scriptContext.UserEventType.CREATE ||
scriptContext.type == scriptContext.UserEventType.EDIT) {
// get bill to index
var Bill = scriptContext.newRecord;
// fails on this call below on create but works on edit
var refno = Bill.getText({ fieldId: 'tranid' });
}
This behavior is described in the API documentation here.
In dynamic mode, you can use getText() without limitation but, in standard mode, limitations exist. In standard mode, you can use this method only in the following cases:
You can use getText() on any field where the script has already used setText().
If you are loading or copying a record, you can use getText on any field except those where the script has already changed the value by using setValue().
Apparently the newRecord object falls under the second criteria. At this point, the object only has values set. tranid will have a value with the transaction's internal ID, but it won't have the transaction name stored. To get the text, you will have to use record.load() to get the full record, or use search.lookupFields() to get just the transaction name.

Retrieving comment(s) on an article - Conduit Project - Thinkster

https://thinkster.io/tutorials/node-json-api/adding-comments-to-articles > Section Retrieving comment(s) on an article.
Environment
Thinkster Conduit Project: Angular<->API(node.js)<->MongoDB
npm(1) (JavaScript): 6.9.0
mongoose : ^4.4.10 (Compass Community Version)
Goal
Store a comment on a (own written) article and retrieve this comment.
Note
To get the local API (for this purpose I used an exact copy of the production ready API supplied by Thinkster on GitHub) working, in particular: posting a comment on an own written article, I had to change in;
Model: User.js UserSchema (2x) >>> .push(id); => .concat([id]);
Route: routes/api/articles.js router.post('/:article/comments', ...) >>> .push(comment); => .concat([comment]);
These changes had something to do with the drop of 'usePushEach' (versions ago). Nothing is mentioned about it in the current supplied documents on thinkster.
The change on the posting route is apparently important: concatenation of comment-objects onto the article when posting a comment, but it works (see pictures).
Passes
Storage of a comment on a own written article (checked and tested
with Postman & Mongo)
Remove of the comment (checked and tested with Postman & Mongo)
Problem!
Can NOT retrieve, by all means, comment(s) on a own written article (as a list [GET-route]). Somehow the 'comment'-objects are correctly mapped back to the article.
Question: How to solve this? Is this under construction? How to do a callback of the function in which the 'comment' (as argument) has to be mapped back to the article? This argument 'comment' seems to be a empty object, see picture 5: line 356: comment.toJSONFor(user) ???,
In addition, I noticed, on the conduit client talking to the remote 'production-ready' api, own written articles ar not listed as own feed, however they do appear in de global list.
1) Storage of a comment on a own writer article works fine
2) Mongo Db:
3) Retrieve (.get) comments by Postman:
4) Response on the terminal:
5) Section of the Json:
Solution
The problem occurred by two pitfalls:
The promise 'comment' does not get aborted
It is not possible to 'push' directly into the 'req.article.comments' array property
Fixes
In the original code (GitHub) the .catch(next) is fit on the User [Document], this
stopper needs to sit on the promise stream 'comment' instead.
'Old fashion' JavaScript is needed to keep track of existing comment ids, load them separately into a new Array and push the new comment id onto it (so far pushing is allowed). Also the very first comment id on a article needs to be stored in an array type variable.
In both cases a new created array is allowed to map (=) onto the 'req.article.comment'-array property; pushing on it causes an $pushAll error and .concat(...) does not work either.
...better Solution
Circumscribe the sync post-route into an asynchronous post-route
But keep fix 2]1

Best practice to pass query conditions in ajax request

I'm writing a REST api in node js that will execute a sql query and send the results;
in the request I need to send the WHERE conditions; ex:
GET 127.0.0.1:5007/users //gets the list of users
GET 127.0.0.1:5007/users
id = 1 //gets the user with id 1
Right now the conditions are passed from the client to the rest api in the request's headers.
In the API I'm using sequelize, an ORM that needs to receive WHERE conditions in a particular form (an object); ex: having the condition:
(x=1 AND (y=2 OR z=3)) OR (x=3 AND y=1)
this needs to be formatted as a nested object:
-- x=1
-- AND -| -- y=2
| -- OR ----|
| -- z=3
-- OR -|
|
| -- x=3
-- AND -|
-- y=1
so the object would be:
Sequelize.or (
Sequelize.and (
{x=1},
Sequelize.or(
{y=2},
{z=3}
)
),
Sequelize.and (
{x=3},
{y=1}
)
)
Now I'm trying to pass a simple string (like "(x=1 AND (y=2 OR z=3)) OR (x=3 AND y=1)"), but then I will need a function on the server that can convert the string in the needed object (this method in my opinion has the advantage that the developer writing the client, can pass the where conditions in a simple way, like using sql, and this method is also indipendent from the used ORM, with no need to change the client if we need to change the server or use a different ORM);
The function to read and convert the conditions' string into an object is giving me headache (I'm trying to write one without success, so if you have some examples about how to do something like this...)
What I would like to get is a route capable of executing almost any kind of sql query and give the results:
now I have a different route for everything:
127.0.0.1:5007/users //to get all users
127.0.0.1:5007/users/1 //to get a single user
127.0.0.1:5007/lastusers //to get user registered in the last month
and so on for the other tables i need to query (one route for every kind of request I need in the client);
instead I would like to have only one route, something like:
127.0.0.1:5007/request
(when calling this route I will pass the table name and the conditions' string)
Do you think this solution would be a good solution or you generally use other ways to handle this kind of things?
Do you have any idea on how to write a function to convert the conditions' string into the desired object?
Any suggestion would be appreciated ;)
I would strongly advise you not to expose any part of your database model to your clients. Doing so means you can't change anything you expose without the risk of breaking the clients. One suggestion as far as what you've supplied is that you can and should use query parameters to cut down on the number of endpoints you've got.
GET /users //to get all users
GET /users?registeredInPastDays=30 //to get user registered in the last month
GET /users/1 //to get a single user
Obviously "registeredInPastDays" should be renamed to something less clumsy .. it's just an example.
As far as the conditions string, there ought to be plenty of parsers available online. The grammar looks very straightforward.
IMHO the main disadvantage of your solution is that you are creating just another API for quering data. Why create sthm from scratch if it is already created? You should use existing mature query API and focus on your business logic rather then inventing sthm new.
For example, you can take query syntax from Odata. Many people have been developing that standard for a long time. They have already considered different use cases and obstacles for query API.
Resources are located with a URI. You can use or mix three ways to address them:
Hierarchically with a sequence of path segments:
/users/john/posts/4711
Non hierarchically with query parameters:
/users/john/posts?minVotes=10&minViews=1000&tags=java
With matrix parameters which affect only one path segment:
/users;country=ukraine/posts
This is normally sufficient enough but it has limitations like the maximum length. In your case a problem is that you can't easily describe and and or conjunctions with query parameters. But you can use a custom or standard query syntax. For instance if you want to find all cars or vehicles from Ford except the Capri with a price between $10000 and $20000 Google uses the search parameter
q=cars+OR+vehicles+%22ford%22+-capri+%2410000..%2420000
(the %22 is a escaped ", the %24 a escaped $).
If this does not work for your case and you want to pass data outside of the URI the format is just a matter of your taste. Adding a custom header like X-Filter may be a valid approach. I would tend to use a POST. Although you just want to query data this is still RESTful if you treat your request as the creation of a search result resource:
POST /search HTTP/1.1
your query-data
Your server should return the newly created resource in the Location header:
HTTP/1.1 201 Created
Location: /search/3
The result can still be cached and you can bookmark it or send the link. The downside is that you need an additional POST.

How can I clear an external ID on a record in NetSuite?

I need to clear/reset the external ID on a record in NetSuite, but nothing I do is working.
Some of the InventoryItem records are incorrectly mapped to records in another system. I have an application that can sync up the two systems, but I need to clear NetSuite's external IDs first.
Responses don't really need to be SOAP-specific. If you know how to do it with some specific NetSuite/SuiteTalk client, that might point me in the right direction.
What I've Tried
First up, I tried using the nullFieldList... but maybe it doesn't work because externalId is an attribute, not an element?
<messages:update>
<messages:record internalId="7777" xsi:type="accounting:InventoryItem">
<core:nullFieldList xsi:type="core:NullField">
<core:name>externalId</core:name>
</core:nullFieldList>
</messages:record>
</messages:update>
The external ID is just a string, so I tried just setting it to blank. Didn't work either.
<messages:update>
<messages:record internalId="7777" xsi:type="accounting:InventoryItem">
<accounting:externalId></accounting:externalId>
</messages:record>
</messages:update>
I even tried setting the external ID to 0, but I get back a "not unique identifier" error
<messages:update>
<messages:record internalId="7777" xsi:type="accounting:InventoryItem">
<accounting:externalId>0</accounting:externalId>
</messages:record>
</messages:update>
Other Info
I'm using NetSuite's SOAP API v.2013_1
When I say "it doesn't work", I mean: after I do the update, I get a success response similar to the following:
<readResponse>
<platformCore:status isSuccess="true" xmlns:platformCore="urn:core_2013_1.platform.webservices.netsuite.com"/>
<record internalId="7777" externalId="42" xsi:type="listAcct:InventoryItem" xmlns:listAcct="urn:accounting_2013_1.lists.webservices.netsuite.com">
<!-- snip -->
</record>
</readResponse>
If you are using scripts in netsuite you can run a scheduled script to clear records in NS by loading each record and setting the externalid to '' using the following simple code:
var rec= nlapiLoadRecord(type,id);
rec.setFieldValue('externalid','');
nlapiSubmitRecord(rec);
This seemed to work for me in my enviornment which was on 2015.2.
Unfortunately my understanding is that once you set an externalid you cannot clear it, you can set it to another value, but not back to null. I have experienced this both using SuiteScript as well as a Boomi process that uses the 2014.1 endpoint. This may have changed in the recent releases, as I have not tried it recently with SuiteScript nor with a newer endpoint.
You can eliminate the externalId on a record once it's been set. Here's an example using the NetSuite gem:
ns_customer = NetSuite::Records::Customer.get external_id: 'ext_id'
ns_customer.external_id = ''
ns_customer.update
Here's the corresponding XML for update:
<env:Body>
<platformMsgs:update>
<platformMsgs:record xsi:type="listRel:Customer" platformMsgs:internalId="199113" platformMsgs:externalId=""/>
</platformMsgs:update>
</env:Body>
I have had to attempt this before as well. I know the pains you describe. I ended up putting a "-" in front of my external ID to unlink it between my systems. You can do this in SOAP or even as a simple one time csv upload. As it was one time, I did csv.

Codeigniter routing URL with product name to product id

I need to redirect the URLs like this http://mysite.com/store/store-name to http://mysite.com/stores/products/store-id. Note that i need to get the store id from the database. So is it possible to do db operations in routes.php?
And in documentation the syntax is give as $route['store/:any']. How to get the value of second parameter here which is mentioned as :any.
There's not really any good nor simple way of running database queries through the routes. You can however have in the beginning of the controller function a validation.
I asume your store-name is some sort of slug for the product? Basicly you can validate if value is numeric or not, and if not find by slug and then redirect.
config/routes.php
$route["store/(.*)"] = 'stores/products/$1';
/* () and $1 together passes the values */
controllers/stores.php
/* Class etc. */
function products($mix) {
if (is_numeric($mix))
$int_id = $mix;
else {
$row = $this->get_where('products', array('slug' => $mix))->row();
$this->load->helper('url');
redirect("stores/products/{$row->id}");
}
/* Do stuff with the $int_id */
}
This asumes that you have:
A table named products
A column named id that's your products id
A column named slug that that's based on your store-name
I may be a little late to the party, but I may have an alternative suggestion.
I use the following for my routes:
http://mysite.com/store/1/store-name
Reason being... Based on your method, if you create
http://mysite.com/store/store-name
but then after a period of time (of which no doubt Google has indexed your page) you decide for what ever reason you have to change the name of the store to "Wonderful store name", you would naturally change your link to
http://mysite.com/store/wonderful-store-name
Which kills your SEO and any index links.
My solution of using http://mysite.com/store/1/store-name means that you can change store-name to anything you want, but it will always reference 1 meaning the user will still see the related page.
Anything is possible with CodeIgniter routes. Its all in the way you code it. Routing in CI is really flexible. You can use regular expressions besides the standard CI wildcards (:any)(:num). You can even add prefixes or suffixes to the path variables if you have to like:
$route['store/(:any)'] = "redircontroller/redirfunction/$1";
// for instance the namelookup method of the mystores controller
$route['stores/products/(:any)'] = "mystores/namelookup/$1";
You get the second parameter(and third and so on) by defining the variables in your route value which get passed to the controller method you define. If 'products' in you new url is also a variant you should start your wildcard expression there instead. You could also pull parameters out of the url using the URI class ($this->uri->segment(n)).
You don't, however, do database operations in routes.php. You do your database operations in the controller where you route to. My guess is that you'll have to match the store id using whatever is used in the url in a query.
In any case the path that you are using the routes file for is the path the user will see. To do the redirect you have to accept the original path and then redirect the user to the new path like so:
// in some controller that's attached to the original url
public function redirfunct($var){
$this->load->helper('url');
redirect(base_url('stores/products/' . $var));
}
I hope this helps you.
Yes that is easy, you only need to show the ID instead of the name,
you must be doing like storeName> Click to view details
Make it as
storeId> Click to view details
and when you are passing the parameter to the database, change the check of mysql, change it to id instead of name , that can be some like
" select yourRequiredColumn from table_name where id=".parameter."
Thanks

Resources